diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 5b621fac0..2392f33c6 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,4 @@ # These are supported funding model platforms +github: wekan custom: ['https://wekan.fi/commercial-support/'] diff --git a/.github/workflows/depsreview.yaml b/.github/workflows/depsreview.yaml index 8461b453c..ae5ae5989 100644 --- a/.github/workflows/depsreview.yaml +++ b/.github/workflows/depsreview.yaml @@ -9,6 +9,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: 'Dependency Review' uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 54af974ce..febfde53f 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 # Login against a Docker registry except on PR # https://github.com/docker/login-action @@ -48,7 +48,7 @@ jobs: # https://github.com/docker/metadata-action - name: Extract Docker metadata id: meta - uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml index 14f8dfe01..0f85c0d96 100644 --- a/.github/workflows/dockerimage.yml +++ b/.github/workflows/dockerimage.yml @@ -15,6 +15,6 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Build the Docker image run: docker build . --file Dockerfile --tag wekan:$(date +%s) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9d93b7588..0c05c85e6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: fetch-depth: 0 diff --git a/.github/workflows/test_suite.yml b/.github/workflows/test_suite.yml index b3498f613..1b3effdac 100644 --- a/.github/workflows/test_suite.yml +++ b/.github/workflows/test_suite.yml @@ -18,7 +18,7 @@ jobs: # runs-on: ubuntu-latest # steps: # - name: checkout -# uses: actions/checkout@v5 +# uses: actions/checkout@v6 # # - name: setup node # uses: actions/setup-node@v1 @@ -42,7 +42,7 @@ jobs: # needs: [lintcode] # steps: # - name: checkout -# uses: actions/checkout@v5 +# uses: actions/checkout@v6 # # - name: setup node # uses: actions/setup-node@v1 @@ -65,7 +65,7 @@ jobs: # needs: [lintcode,lintstyle] # steps: # - name: checkout -# uses: actions/checkout@v5 +# uses: actions/checkout@v6 # # - name: setup node # uses: actions/setup-node@v1 @@ -90,12 +90,12 @@ jobs: # CHECKOUTS - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 # CACHING - name: Install Meteor id: cache-meteor-install - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ~/.meteor key: v1-meteor-${{ hashFiles('.meteor/versions') }} @@ -104,7 +104,7 @@ jobs: - name: Cache NPM dependencies id: cache-meteor-npm - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ~/.npm key: v1-npm-${{ hashFiles('package-lock.json') }} @@ -113,7 +113,7 @@ jobs: - name: Cache Meteor build id: cache-meteor-build - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: | .meteor/local/resolver-result-cache.json @@ -136,7 +136,7 @@ jobs: run: sh ./test-wekan.sh -cv - name: Upload coverage - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: coverage-folder path: .coverage/ @@ -147,10 +147,10 @@ jobs: needs: [tests] steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Download coverage - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v7 with: name: coverage-folder path: .coverage/ diff --git a/.meteor/packages b/.meteor/packages index 95e40c00c..e0baa96d9 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -52,8 +52,8 @@ ongoworks:speakingurl raix:handlebar-helpers http@2.0.0! # force new http package -# Datepicker -wekan-bootstrap-datepicker +# Datepicker (disabled - using native HTML inputs) +# wekan-bootstrap-datepicker # UI components ostrio:i18n @@ -93,4 +93,4 @@ ejson@1.1.3 logging@1.3.3 wekan-fullcalendar momentjs:moment@2.29.3 -wekan-fontawesome +# wekan-fontawesome diff --git a/.meteor/versions b/.meteor/versions index fbf430721..886c8cb4a 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -155,8 +155,6 @@ wekan-accounts-cas@0.1.0 wekan-accounts-lockout@1.0.0 wekan-accounts-oidc@1.0.10 wekan-accounts-sandstorm@0.8.0 -wekan-bootstrap-datepicker@1.10.0 -wekan-fontawesome@6.4.2 wekan-fullcalendar@3.10.5 wekan-ldap@0.0.2 wekan-markdown@1.0.9 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0834f213b..8b27c474d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,355 @@ Fixing other platforms In Progress. [Upgrade WeKan](https://wekan.fi/upgrade/) +WeKan 8.00-8.06 had wrong raw database directory setting /var/snap/wekan/common/wekan and some cards were not visible. +Those are fixed at WeKan 8.07 where database directory is back to /var/snap/wekan/common and all cards are visible. + +# Upcoming WeKan ® release + +This release adds the following updates: + +- [Update GitHub docker/metadata-action from 5.8.0 to 5.9.0](https://github.com/wekan/wekan/pull/6012). + Thanks to dependabot. +- [Updated security.md](https://github.com/wekan/wekan/commit/7ff1649d8909917cae590c68def6eecac0442f91). + Thanks to xet7. +- [Updated build script for Linux arm64 bundle](https://github.com/wekan/wekan/commit/3db1305e58168f7417023ccd8d54995026844b18). + Thanks to xet7. + +and fixes the following bugs: + +- [Fix Broken Strikethroughs in Markdown to HTML conversion](https://github.com/wekan/wekan/pull/6009). + Thanks to brlin-tw. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.17 2025-11-06 WeKan ® release + +This release adds the following new feature: + +- [Feature: Workspaces, at All Boards page](https://github.com/wekan/wekan/commit/0afbdc95b49537e06b4f9cf98f51a669ef249384). + Thanks to xet7. + +and fixes the following bugs: + +- [Fix 8.16: Switching Board View fails with 403 error](https://github.com/wekan/wekan/commit/550d87ac6cb3ec946600616485afdbd242983ab4). + Thanks to xet7. +- [Moved migrations from opening board to right sidebar / Migrations](https://github.com/wekan/wekan/commit/1b25d1d5720d4f486a10d2acce37e315cf9b6057). + Thanks to xet7. +- [Fix 8.16 Lists with no items are deleted every time when board is opened. Moved migrations to right sidebar](https://github.com/wekan/wekan/commit/7713e613b431e44dc13cee72e7a1e5f031473fa6). + Thanks to xet7. +- [Remove old translations and code not in use anymore](https://github.com/wekan/wekan/commit/ba49d4d140bc0d4cfb5a96db9ab077bc85db58f1). + Thanks to xet7. +- [Fixed sidebar migrations to be per-board, not global. Clarified translations](https://github.com/wekan/wekan/commit/e4638d5fbcbe004ac393462331805cac3ba25097). + Thanks to xet7. +- [Fix star board](https://github.com/wekan/wekan/commit/8711b476be30496b96b845529b5717bb6e685c27). + Thanks to xet7. +- [Fix Card emoji issues](https://github.com/wekan/wekan/commit/e5e711c938edcca23c974c3eec97296898bcf24e). + Thanks to xet7. +- [Try to fix Edit Custom Fields button not working. Removed duplicate option from Boards Settings](https://github.com/wekan/wekan/commit/20af0a2ef55b11e7205845859ee92a929616ce91). + Thanks to xet7. +- [Fix Regression - calendar popup to set due date has gone](https://github.com/wekan/wekan/commit/581733d605b7e0494e72229c45947cff134f6dd6). + Thanks to xet7. +- [Remove not working Bookmark menu option](https://github.com/wekan/wekan/commit/c829c073cf822e48b7cd84bbfb79d42867412517). + Thanks to xet7. +- [Fix Workspaces at All Boards to have correct count of remaining etc, while starred also at Starred/Favorites](https://github.com/wekan/wekan/commit/6244657ca53a54646ec01e702851a51d89bd0d55). + Thanks to xet7. +- [Fix Worker Permissions does not allow for cards to be moved. - v8.15. Removed buttons Worker should not use](https://github.com/wekan/wekan/commit/18003900c2d497c129793d1653d4d9872a2f19da). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.16 2025-11-02 WeKan ® release + +This release fixes SpaceBleed that is the following CRITICAL SECURITY ISSUES: + +- [Fix SECURITY ISSUE 1: File Attachments enables stored XSS (High)](https://github.com/wekan/wekan/commit/e9a727301d7b4f1689a703503df668c0f4f4cab8). + Thanks to Siam Thanat Hack (STH) and xet7. +- [Fix SECURITY ISSUE 2: Access to boards of any Orgs/Teams, and avatar permissions](https://github.com/wekan/wekan/commit/f26d58201855e861bab1cd1fda4d62c664efdb81). + Thanks to Siam Thanat Hack (STH) and xet7. +- [Fix SECURITY ISSUE 3: Unauthenticated (or any) user can update board sort](https://github.com/wekan/wekan/commit/ea310d7508b344512e5de0dfbc9bdfd38145c5c5). + Thanks to Siam Thanat Hack (STH) and xet7. +- [Fix SECURITY ISSUE 4: Members can forge others’ votes (Low). Bonus: Similar fixes to planning poker too done by xet7](https://github.com/wekan/wekan/commit/0a1a075f3153e71d9a858576f1c68d2925230d9c). + Thanks to Siam Thanat Hack (STH) and xet7. +- [Fix SECURITY ISSUE 5: Attachment API uses bearer value as userId and DoS (Low)](https://github.com/wekan/wekan/commit/ccd90343394f433b287733ad0a33c08e0a71f53c). + Thanks to Siam Thanat Hack (STH) and xet7. + +and adds the following new features: + +- [List menu / More / Delete duplicate lists that do not have any cards](https://github.com/wekan/wekan/commit/91b846e2cdee9154b045d11b4b4c1a7ae1d79016). + Thanks to xet7. +- [Disabled migrations that happen when opening board. Defaulting to per-swimlane lists and drag drop list to same or different swimlane](https://github.com/wekan/wekan/commit/034dc08269520ca31c780cce64e0150969e9228e). + Thanks to xet7. + +and fixes the following bugs: + +- [Fix changing swimlane color to not reload webpage](https://github.com/wekan/wekan/commit/ecf2418347cae4329deb292b534f68eb099d3f90). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.15 2025-10-23 WeKan ® release + +This release fixes the following bugs: + +- Fix drag lists did not work + [Part 1](https://github.com/wekan/wekan/commit/8662c96d1c8d4fa76ce7b31eb06678ad59c3ebe1), + [Part 2](https://github.com/wekan/wekan/commit/0cebd8aa4dbe0bf2418b814716744ab806b671c2). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.14 2025-10-23 WeKan ® release + +This release fixes the following bugs: + +- [Fix board reloading page every second](https://github.com/wekan/wekan/commit/b4b598f542d0cefc5f2d5d6c7286f0a312cf6a55). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.12 2025-10-23 WeKan ® release + +This release fixes the following bugs: + +- [Fix Regression - unable to view cards by due date v8.11](https://github.com/wekan/wekan/commit/ae11e80bde79d9ad412d185f20e5a7f802685260). + Thanks to xet7. +- [Fix Regression - unable to rearrange tasks within a checklist - v8.11](https://github.com/wekan/wekan/commit/544b24ceb1687e5b568d8c7b74403a5a2e3f6bc6). + Thanks to xet7. +- [Fix unable to add members to board](https://github.com/wekan/wekan/commit/c6d46006837a29fb311e444f94fa65f236e23bc7). + Thanks to xet7. +- [Removed not needed | at left side of minicard badges](https://github.com/wekan/wekan/commit/a0c30c35ed57113df041ef1020d3e9e5449f35e4). + Thanks to xet7. +- [Fix opened card Date Format to be used at dates popups](https://github.com/wekan/wekan/commit/7ca81285b14d1ec60d6e7e9c191d1194950f18c8). + Thanks to xet7. +- [Fix UI issues of Right Sidebar / Subtasks Settings and Card Settings](https://github.com/wekan/wekan/commit/45537ede870eca59ad72cd7ad013a12f60032df4). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.11 2025-10-21 WeKan ® release + +This release fixes the following bugs: + +- [Fix due dates to use colors: red = overdue, amber = due soon, no shade = not due yet](https://github.com/wekan/wekan/commit/1aa0d849775fbd0dfc83fa8e4cdca84d22a15042). + Thanks to xet7. +- [Fix My Due Cards to be sorted by due date, oldest first](https://github.com/wekan/wekan/commit/a540b12895520f398bce10bd244f733d221975d4). + Thanks to xet7. +- [Verify that due background colors are correct also at My Due Cards](https://github.com/wekan/wekan/commit/665c9b5e522e73115a1515ced066037110db84e1). + Thanks to xet7. +- [Fix Regression - due date taking a while to load all cards v8.06](https://github.com/wekan/wekan/commit/347fa9e5cd89d064ebb8ab544e20a41f52206db6). + Thanks to xet7. +- Fix duplicated lists. + [Part 1](https://github.com/wekan/wekan/commit/b6e7b258e0e8caecafc553dceb5771985992a0f9), + [Part 2](https://github.com/wekan/wekan/commit/b7ca2310b2cdec7db204229b2d5b9f95b6da8c7d), + [Part 3](https://github.com/wekan/wekan/commit/58df525b4915a99d0f603cc2536fd1fad1d20b29). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.10 2025-10-21 WeKan ® release + +This release fixes the following bugs: + +- [Prevent opened board re-migrating and reloading every 5 seconds](https://github.com/wekan/wekan/commit/4987a95d8e35fc4cd30010fd17722ee94037d7f2). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.09 2025-10-21 WeKan ® release + +This release fixes the following bugs: + +- [Fix Admin Panel / People editing and layout](https://github.com/wekan/wekan/commit/7a585a3dfb080af51f88669ea5928f715779cee4). + Thanks to xet7. +- [Fix upgrade to 8.08 duplicates lists](https://github.com/wekan/wekan/commit/c3a405222782a4a91eb8725faaa8309f0926dcc4). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.08 2025-10-21 WeKan ® release + +This release fixes the following bugs: + +- [Fix opening board migration of Shared Lists to Per-Swimlane lists to use ReactiveCache correctly without errors](https://github.com/wekan/wekan/commit/9536e60bd1c77c8a22e89d2eb2968e11da3a28cd). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.07 2025-10-20 WeKan ® release + +This release fixes the following bugs: + +- [Fix Snap Candidate WeKan 8.00-8.06 commit ae01ea5 database directory from /var/snap/wekan/common/wekan back to 8.07 /var/snap/wekan/common](https://github.com/wekan/wekan/commit/98f141d62f3b6d4371d024c72eae6688d0f4e516). + Thanks to xet7. +- [When opening board, add missing lists](https://github.com/wekan/wekan/commit/80777b46638ed15b8194105751499ada4b066d19). + Thanks to xet7. +- [If Snap Candidate MongoDB raw database files were at SNAP_COMMON/wekan, migrate them back to SNAP_COMMON](https://github.com/wekan/wekan/commit/f2019b1059c8d6f4cd9a46c3db7e004c4928cebb). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.06 2025-10-20 WeKan ® release + +This release adds the following new features: + +- [At Public Board, drag resize list width and swimlane height. For logged in users, fix adding labels](https://github.com/wekan/wekan/commit/351433524708e9a7ccb4795d9ca31a78904943ea). + Thanks to xet7. +- [When opening board, migrate from Shared Lists to Per-Swimlane Lists](https://github.com/wekan/wekan/commit/1e6252de7f26f3af14a99fb63b5dac27ba0576f3). + Thanks to xet7. +- [Added Date Format setting to Opened Card](https://github.com/wekan/wekan/commit/2dd3916f7ee3df10bd88643cf2c796cb166b3044). + Thanks to xet7. + +and fixes the following bugs: + +- [Fix add and drag drop attachments to minicards and card](https://github.com/wekan/wekan/commit/b06daff4c7e63453643459f7d8798fde97e3200c). + Thanks to xet7. +- [Fix starred, archive and clone icons](https://github.com/wekan/wekan/pull/5953). + Thanks to helioguardabaxo. +- Fix Due dates to be color coded and have unicode icons. + [Part 1](https://github.com/wekan/wekan/commit/d965faa3174dc81636106e6f81435b2750b0625f), + [Part 2](https://github.com/wekan/wekan/commit/101048339bdd1e45f876aeb1aa5ec32ceda28139). + Thanks to xet7. +- [Fix unable to see My Due Cards](https://github.com/wekan/wekan/commit/66b444e2b0c9b2ed5f98cd1ff0cd9222b2d0c624). + Thanks to xet7. +- Fix drag drop lists. + [Part 1](https://github.com/wekan/wekan/commit/324f3f7794aace800022a24deb5fd5fb36ebd384), + [Part 2](https://github.com/wekan/wekan/commit/ff516ec696ef499f11b04b30053eeb9d3f96d8d1). + Thanks to xet7. +- [Removed extra pipe characters](https://github.com/wekan/wekan/commit/caa6e615ff3c3681bf2b470a625eb39c6009b825). + Thanks to xet7. +- [Fix syntax error at migrations](https://github.com/wekan/wekan/commit/eb6b42c4c9f99894fd93e62c9b3fceda3429c96c). + Thanks to xet7. +- [Fix opened card attachments button text to be at tooltip, not at opened card](https://github.com/wekan/wekan/commit/1e53125499ef563ca3c65f786ac3525e5f50274c). + Thanks to xet7. +- [Fix Broken Hyperlinks in Markdown to HTML conversion](https://github.com/wekan/wekan/commit/973a49526fdf22c143468d3d9db64269b1defa7d). + Thanks to xet7. +- [Fix migrations](https://github.com/wekan/wekan/commit/0acbf30b0346f49c0ee8f5161fb00b4eca8e1a0c). + Thanks to xet7. +- [Fix card popup to use HTML date, not anymore JQuery date](https://github.com/wekan/wekan/commit/2d44881619d78e8ef4c5060d17e9035f5babd778). + Thanks to xet7. +- [Fix Bug: Scale of Minicard icons is linked to horizontal screensize](https://github.com/wekan/wekan/commit/b6b0c5fe6d7dbd37926c662f96f2e3653cabd867). + Thanks to xet7. +- [Fix Bug Member settings drops to the second line and overlaps when many boards are starred as favourites](https://github.com/wekan/wekan/commit/46d46e313cbb8d9c3e4a976ec27b5141c266050f). + Thanks to xet7. +- [Some mobile view fixes](https://github.com/wekan/wekan/commit/c4af4d03acc02f3e54e91f2a65bce2f88742b1a6). + Thanks to xet7. +- [Have all iPhone use mobile view by default, while still having possibility to use mobile/desktop switch button for desktop mode](https://github.com/wekan/wekan/commit/5df4efd7ba06e618e454f068df05885306283bb1). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.05 2025-10-17 WeKan ® release + +This release fixes the following bugs: + +- [Show original positions of swimlanes, lists and cards](https://github.com/wekan/wekan/commit/2543df94252c2789fb484ae52b9a6ff298252ceb). + Thanks to xet7. +- Fix popups issues at Edit Avatar, Archive card confirm, etc. + [Part 1](https://github.com/wekan/wekan/commit/87ae085e6d0a56a2083eec819cf7d795d3e51e1a), + [Part 2](https://github.com/wekan/wekan/commit/386aea7c788d6eaf9d486ead4d81453401adf390). + Thanks to xet7. +- [Changed wekan-boostrap-datepicker to HTML datepicker](https://github.com/wekan/wekan/commit/79b94824efedaa9e256de931fd26398eb2838d6a). + Thanks to xet7. +- [Replaced moment.js with Javascript date](https://github.com/wekan/wekan/commit/cb6afe67a7363af89663ba17392dc5f90a15f703). + Thanks to xet7. +- [Convert Font Awesome to Unicode Icons. Part 1. In Progress](https://github.com/wekan/wekan/commit/2947238a021b6952b56e828d49a8c0094520d89a). + Thanks to xet7. +- [Resize height of swimlane by dragging. Font Awesome to Unicode icons](https://github.com/wekan/wekan/commit/09631d6b0c1b8e3bbc3bf45d4bb65449b46f1288). + Thanks to xet7. +- [Removed not needed visible text from mobile desktop switch button](https://github.com/wekan/wekan/commit/62ede481966107405460f6d5b90f292c98bae254). + Thanks to xet7. +- Font Awesome to Unicode icons. + [Part 3](https://github.com/wekan/wekan/commit/3af94c2a9059a399b9f9946c387caff892ace2f9). + [Part 4](https://github.com/wekan/wekan/commit/088bc16072ea0dd02aa2dec6a2e3e9aed00a3cc9). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.04 2025-10-16 WeKan ® release + +This release fixes the following bugs: + +- [Make sure that all cards are visible](https://github.com/wekan/wekan/commit/6b848b318d62afe9772218febdb09c7426774f60). + Thanks to xet7. +- [Fix wide screen](https://github.com/wekan/wekan/commit/f08c7702eecf23588f7bc023beefb453edd704c6). + Thanks to xet7. +- Fix popups positioning. + [Part 1](https://github.com/wekan/wekan/commit/77eea4d494e5db8e2c0e59732bcea73aa163bc13), + [Part 1](https://github.com/wekan/wekan/commit/00ddec75754bbbccc6fb9b3096495b9609246480). + Thanks to xet7. +- [Remove using fork with MongoDB at Snap](https://github.com/wekan/wekan/commit/690481c138f9629054180310dd172295c7f6d34e). + Thanks to xet7. +- [Use only MongoDB 7 at Snap](https://github.com/wekan/wekan/commit/79e83e33ec1dcec4eea81d5fb4a9f7381c176a12). + Thanks to xet7. +- [Removed extra npm packages](https://github.com/wekan/wekan/commit/dd88483ec7526eee4a97bac5f09e03985be5d923). + Thanks to xet7. +- [Try to fix Broken Hyperlinks in Markdown to HTML conversion](https://github.com/wekan/wekan/commit/bbbd3abf06e45a3fa57c4aa987d87f1873eb11d6). + Thanks to xet7. +- [Disable not working minio and s3 support temporarily](https://github.com/wekan/wekan/commit/4283b5b0e330930fff1fa2bb73c355a4ffb4cda0). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.03 2025-10-14 WeKan ® release + +This release fixes the following bugs: + +- [Fix Snap MongoDB to not fork at systemd, so it stays running](https://github.com/wekan/wekan/commit/5792a869594b4c79a93db414b95a13d60013193b). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + +# v8.02 2025-10-14 WeKan ® release + +This release adds the following new features: + +- [Run database migrations when opening board. Not when upgrading WeKan](https://github.com/wekan/wekan/commit/2b5c56484a4dd559f062ef892fd5248a903b2a10). + Thanks to xet7. +- [Added Cron Manager to Admin Panel for long running jobs, like running migrations when opening board, copying or moving boards swimlanes lists cards etc](https://github.com/wekan/wekan/commit/da68b01502afc9d5d9ea1267bee9fc98bb08b611). + Thanks to xet7. +- [If there is no cron jobs running, run migrations for boards that have not been opened yet](https://github.com/wekan/wekan/commit/317138ab7209a41715336ea8251df45f11a6d173). + Thanks to xet7. +- [Accessibility improvements](https://github.com/wekan/wekan/commit/67b078b8056ec9851caaf6ef855719de1e6d966d). + Thanks to xet7. +- [Change list width by dragging between lists](https://github.com/wekan/wekan/commit/abad8cc4d5dded0f5e1a80892a3b29aa71404a5c). + Thanks to xet7. + +and adds the following updates: + +- [Updated dependencies](https://github.com/wekan/wekan/commit/5bc03b23ea34816d8e1135cbe9ed5f18a2573854). + Thanks to developers of dependencies. + +and fixes the following bugs: + +- [Fixes to make board showing correctly](https://github.com/wekan/wekan/commit/bd8c565415998c9aaded821988d591105258b378). + Thanks to xet7. +- [Fix opening sidebar](https://github.com/wekan/wekan/commit/0fd781e80aaf841c26ce59caffc579b9c391330f). + Thanks to xet7. +- [Fix Admin Panel menus "Attachment Settings" and "Cron Settings" and make them translateable](https://github.com/wekan/wekan/commit/033919a2702fa6959b8f8c87f076d3f255ace6ba). + Thanks to xet7. +- Change Admin Panel "Attachment Settings" and "Cron Settings" options to be tabs, not submenu. + [Part 1](https://github.com/wekan/wekan/commit/ae2aa1f5cd2511e80e12a91426eb91bb968dff98), + [Part 2](https://github.com/wekan/wekan/commit/5a6faafa30fefcd5dd0af7cc52b847a54d538065), + [Part 3](https://github.com/wekan/wekan/commit/2148aeea42f69fa367bf8c451d7f1c3a63b52880). + Thanks to xet7. +- [Fixed Error in migrate-lists-to-per-swimlane migration](https://github.com/wekan/wekan/commit/cc99da5357fb1fc00e3b5aece20c57917f88301b). + Thanks to xet7. +- Fix Admin Panel Settings menu to show Attachments and Cron options correctly. + [Part 1](https://github.com/wekan/wekan/e0013b9b631eb16861b1cfdb25386bf8e9099b4e), + [Part 2](https://github.com/wekan/wekan/7bb1e24bda2ed9db0bad0fafcf256680c2c05e8a). +- [Fixed migrations](https://github.com/wekan/wekan/commit/63c314ca185aeda650c01b4a67fcde1067320d22). + Thanks to xet7. +- [Removed not needed console log message](https://github.com/wekan/wekan/commit/0a34ee1b6437dcfd65e31d9bbc9f3ccfa5718ba9). + Thanks to xet7. +- [Updated mobile Bookmarks/Starred boards. Part 1. In Progress](https://github.com/wekan/wekan/commit/da98942cce37363d6062695d3c4cf7e2df796cac). + Thanks to xet7. +- [Fix drag drop reorder swimlanes](https://github.com/wekan/wekan/commit/a4518bbefc99be74f7ccfdbb9fdf902007ca90f3). + Thanks to xet7. +- [Try to fix swimlane hamburger menu popup positioning. In progress](https://github.com/wekan/wekan/commit/d4f13de1d978b271d05e1d67d40e3c1c14761578). + Thanks to xet7. + +Thanks to above GitHub users for their contributions and translators for their translations. + # v8.01 2025-10-11 WeKan ® release This release adds the following new features: @@ -90,7 +439,7 @@ and adds the following new features: - [Mobile one board per row. Board zoom size percent. Board toggle mobile/desktop mode. In Progress](https://github.com/wekan/wekan/commit/752699d1c2fb8ea9ff0f3ec9ae0b2b776443d826). Thanks to xet7. -- [Drag any files from file manager to minicard or opened card. +- Drag any files from file manager to minicard or opened card. [Part 1](https://github.com/wekan/wekan/commit/3e9481c5bd2c02ba501bd0a6ef1d1e6ce82bb1d9), [Part 2](https://github.com/wekan/wekan/commit/cdd7d69c660d0b6ac06b7b75d4f59985b8a9322a). Thanks to xet7. diff --git a/Dockerfile b/Dockerfile index 0612f3149..aedb88c5b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -249,9 +249,9 @@ cd /home/wekan/app # Remove legacy webbroser bundle, so that Wekan works also at Android Firefox, iOS Safari, etc. #rm -rf /home/wekan/app_build/bundle/programs/web.browser.legacy #mv /home/wekan/app_build/bundle /build -wget "https://github.com/wekan/wekan/releases/download/v8.01/wekan-8.01-amd64.zip" -unzip wekan-8.01-amd64.zip -rm wekan-8.01-amd64.zip +wget "https://github.com/wekan/wekan/releases/download/v8.17/wekan-8.17-amd64.zip" +unzip wekan-8.17-amd64.zip +rm wekan-8.17-amd64.zip mv /home/wekan/app/bundle /build # Put back the original tar diff --git a/SECURITY.md b/SECURITY.md index aadecbf6e..5cde5926b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,12 +1,20 @@ -About money, see [CONTRIBUTING.md](CONTRIBUTING.md) -Security is very important to us. If you discover any issue regarding security, please disclose -the information responsibly by sending an email from Protonmail to security@wekan.fi -that is Protomail email address, or by using this PGP key -[security-at-wekan.fi.asc](security-at-wekan.fi.asc) to security@wekan.fi -and not by creating a GitHub issue. We will respond swiftly to fix verifiable security issues. +## Responsible Security Disclosure -We thank you with a place at our hall of fame page, that is at https://wekan.fi/hall-of-fame +- To send email, use [ProtonMail](https://proton.me) email address or use PGP key [security-at-wekan.fi.asc](security-at-wekan.fi.asc) +- Send info about security issue ONLY to security@wekan.fi (that is Protomail email address). NOT TO ANYWHERE ELSE. NO CC, NO BCC. +- Wait for new WeKan release that fixes security issue +- If you approve, we thank you by adding you to Hall of Fame: https://wekan.fi/hall-of-fame/ + +## Bonus Points + +- If you include code for fixing security issue + +## Losing Points + +- If you ask about [bounty](CONTRIBUTING.md). There is no bounty. WeKan is NOT Big Tech. WeKan is FLOSS. +- If you forget to include vulnerability details. +- If you send info about security issue to somewhere else than security@wekan.fi ## How should reports be formatted? @@ -26,7 +34,7 @@ CWSS (optional): %cwss Anyone who reports a unique security issue in scope and does not disclose it to a third party before we have patched and updated may be upon their approval -added to the Wekan Hall of Fame. +added to the WeKan Hall of Fame https://wekan.fi/hall-of-fame/ ## Which domains are in scope? @@ -63,11 +71,6 @@ and by by companies that have 30k users. - If you are thinking about TLS MITM, look at https://github.com/caddyserver/caddy/issues/2530 - Let's Encrypt TLS requires publicly accessible webserver, that Let's Encrypt TLS validation servers check. - If firewall limits to only allowed IP addresses, you may need non-Let's Encrypt TLS cert. -- For On Premise: - - https://caddyserver.com/docs/automatic-https#local-https - - https://github.com/wekan/wekan/wiki/Caddy-Webserver-Config - - https://github.com/wekan/wekan/wiki/Azure - - https://github.com/wekan/wekan/wiki/Traefik-and-self-signed-SSL-certs ## XSS @@ -172,6 +175,57 @@ Meteor.startup(() => { - https://github.com/wekan/wekan/blob/main/client/components/cards/attachments.js#L303-L312 - https://wekan.github.io/hall-of-fame/filebleed/ +### Attachments: Forced download to prevent stored XSS + +- To prevent browser-side execution of uploaded content under the app origin, all attachment downloads are served with safe headers: + - `Content-Type: application/octet-stream` + - `Content-Disposition: attachment` + - `X-Content-Type-Options: nosniff` + - A restrictive `Content-Security-Policy` with `sandbox` +- This means attachments are downloaded instead of rendered inline by default. This mitigates HTML/JS/SVG based stored XSS vectors. +- Avatars and inline images remain supported but SVG uploads are blocked and never rendered inline. + +## Users: Client update restrictions + +- Client-side updates to user documents are limited to safe fields only: + - `username` + - `profile.*` +- Sensitive fields are blocked from any client updates and can only be modified by server methods with authorization: + - `orgs`, `teams`, `roles`, `isAdmin`, `createdThroughApi`, `loginDisabled`, `authenticationMethod`, `services.*`, `emails.*`, `sessionData.*` +- Attempts to update forbidden fields from the client are denied. +- Admin operations like managing org/team membership or toggling flags must use server methods that check permissions. + +## Voting: integrity and authorization + +- Client updates to card `vote` fields are blocked to prevent forged votes and inconsistent policy enforcement. +- Voting is performed via a server method that enforces: + - Authentication and board membership, or an explicit per-card flag allowing non-members to vote. + - Only the caller's own userId is added/removed from `vote.positive`/`vote.negative`. +- This prevents members from fabricating other users' votes and ensures non-members cannot vote unless explicitly allowed. + +## Planning Poker: integrity and authorization + +- Client updates to card `poker` fields are blocked. All poker actions go through server methods that enforce: + - Authentication and board membership for configuration and results. + - For casting a poker vote, either board membership or an explicit per-card flag allowing non-members to participate. + - Only the caller's own userId is added/removed from the selected estimation bucket (e.g., one, two, five, etc.). +- Methods cover setting/unsetting poker question/end, casting votes, replaying, and setting final estimation. + +## Attachment API: authentication and DoS prevention + +- The attachment API (`/api/attachment/*`) requires proper authentication using `X-User-Id` and `X-Auth-Token` headers. +- Authentication validates tokens by hashing with `Accounts._hashLoginToken` and matching against stored login tokens, preventing identity spoofing. +- Request handlers implement: + - 30-second timeout to prevent hanging connections. + - Request body size limits (50MB for uploads, 10MB for metadata operations). + - Proper error handling and guaranteed response completion. + - Request error event handlers to clean up failed connections. +- This prevents: + - DoS attacks via concurrent unauthenticated or malformed requests. + - Identity spoofing by using arbitrary bearer tokens or user IDs. + - Resource exhaustion from hanging connections or excessive payloads. +- Access control: all attachment operations verify board membership before allowing access. + ## Brute force login protection - https://github.com/wekan/wekan/commit/23e5e1e3bd081699ce39ce5887db7e612616014d @@ -218,9 +272,4 @@ Typical already known or "no impact" bugs such as: - Email spoofing, SPF, DMARC & DKIM. Wekan does not include email server. Wekan is Open Source with MIT license, and free to use also for commercial use. -We welcome all fixes to improve security by email to security@wekan.team - -## Bonus Points - -If your Responsible Security Disclosure includes code for fixing security issue, -you get bonus points, as seen on [Hall of Fame](https://wekan.github.io/hall-of-fame). +We welcome all fixes to improve security by email to security@wekan.fi diff --git a/Stackerfile.yml b/Stackerfile.yml index 55e0e0a16..e0529f92f 100644 --- a/Stackerfile.yml +++ b/Stackerfile.yml @@ -1,5 +1,5 @@ appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928 -appVersion: "v8.01.0" +appVersion: "v8.17.0" files: userUploads: - README.md diff --git a/client/00-startup.js b/client/00-startup.js index 4a717b67c..52a1c536c 100644 --- a/client/00-startup.js +++ b/client/00-startup.js @@ -4,3 +4,61 @@ if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/pwa-service-worker.js'); }); } + +// Import board converter for on-demand conversion +import '/client/lib/boardConverter'; +import '/client/components/boardConversionProgress'; + +// Import migration manager and progress UI +import '/client/lib/migrationManager'; +import '/client/components/migrationProgress'; + +// Import cron settings +import '/client/components/settings/cronSettings'; + +// Mirror Meteor login token into a cookie for server-side file route auth +// This enables cookie-based auth for /cdn/storage/* without leaking ROOT_URL +// Token already lives in localStorage; cookie adds same-origin send-on-request semantics +Meteor.startup(() => { + const COOKIE_NAME = 'meteor_login_token'; + const cookieAttrs = () => { + const attrs = ['Path=/', 'SameSite=Lax']; + try { + if (window.location && window.location.protocol === 'https:') { + attrs.push('Secure'); + } + } catch (_) {} + return attrs.join('; '); + }; + + const setCookie = (name, value) => { + if (!value) return; + document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; ${cookieAttrs()}`; + }; + const clearCookie = (name) => { + document.cookie = `${encodeURIComponent(name)}=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; ${cookieAttrs()}`; + }; + + const syncCookie = () => { + try { + const token = Accounts && typeof Accounts._storedLoginToken === 'function' ? Accounts._storedLoginToken() : null; + if (token) setCookie(COOKIE_NAME, token); else clearCookie(COOKIE_NAME); + } catch (e) { + // ignore + } + }; + + // Initial sync on startup + syncCookie(); + + // Keep cookie in sync on login/logout + if (Accounts && typeof Accounts.onLogin === 'function') Accounts.onLogin(syncCookie); + if (Accounts && typeof Accounts.onLogout === 'function') Accounts.onLogout(syncCookie); + + // Sync across tabs/windows when localStorage changes + window.addEventListener('storage', (ev) => { + if (ev && typeof ev.key === 'string' && ev.key.indexOf('Meteor.loginToken') !== -1) { + syncCookie(); + } + }); +}); diff --git a/client/components/boardConversionProgress.css b/client/components/boardConversionProgress.css new file mode 100644 index 000000000..fd186908f --- /dev/null +++ b/client/components/boardConversionProgress.css @@ -0,0 +1,184 @@ +/* Board Conversion Progress Styles */ +.board-conversion-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.7); + z-index: 9999; + display: none; + align-items: center; + justify-content: center; +} + +.board-conversion-overlay.active { + display: flex; +} + +.board-conversion-modal { + background: white; + border-radius: 8px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); + max-width: 500px; + width: 90%; + max-height: 80vh; + overflow: hidden; + animation: slideIn 0.3s ease-out; +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.board-conversion-header { + padding: 20px 24px 16px; + border-bottom: 1px solid #e0e0e0; + text-align: center; +} + +.board-conversion-header h3 { + margin: 0 0 8px 0; + color: #333; + font-size: 20px; + font-weight: 500; +} + +.board-conversion-header h3 i { + margin-right: 8px; + color: #2196F3; +} + +.board-conversion-header p { + margin: 0; + color: #666; + font-size: 14px; +} + +.board-conversion-content { + padding: 24px; +} + +.conversion-progress { + margin-bottom: 20px; +} + +.progress-bar { + width: 100%; + height: 8px; + background-color: #e0e0e0; + border-radius: 4px; + overflow: hidden; + margin-bottom: 8px; +} + +.progress-fill { + height: 100%; + background: linear-gradient(90deg, #2196F3, #21CBF3); + border-radius: 4px; + transition: width 0.3s ease; + position: relative; +} + +.progress-fill::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient( + 90deg, + transparent, + rgba(255, 255, 255, 0.3), + transparent + ); + animation: shimmer 2s infinite; +} + +@keyframes shimmer { + 0% { + transform: translateX(-100%); + } + 100% { + transform: translateX(100%); + } +} + +.progress-text { + text-align: center; + font-weight: 600; + color: #2196F3; + font-size: 16px; +} + +.conversion-status { + text-align: center; + margin-bottom: 16px; + color: #333; + font-size: 16px; +} + +.conversion-status i { + margin-right: 8px; + color: #2196F3; +} + +.conversion-time { + text-align: center; + color: #666; + font-size: 14px; + background-color: #f5f5f5; + padding: 8px 12px; + border-radius: 4px; + margin-bottom: 16px; +} + +.conversion-time i { + margin-right: 6px; + color: #FF9800; +} + +.board-conversion-footer { + padding: 16px 24px 20px; + border-top: 1px solid #e0e0e0; + background-color: #f9f9f9; +} + +.conversion-info { + text-align: center; + color: #666; + font-size: 13px; + line-height: 1.4; +} + +.conversion-info i { + margin-right: 6px; + color: #2196F3; +} + +/* Responsive design */ +@media (max-width: 600px) { + .board-conversion-modal { + width: 95%; + margin: 20px; + } + + .board-conversion-header, + .board-conversion-content, + .board-conversion-footer { + padding-left: 16px; + padding-right: 16px; + } + + .board-conversion-header h3 { + font-size: 18px; + } +} diff --git a/client/components/boardConversionProgress.jade b/client/components/boardConversionProgress.jade new file mode 100644 index 000000000..37a404d90 --- /dev/null +++ b/client/components/boardConversionProgress.jade @@ -0,0 +1,27 @@ +template(name="boardConversionProgress") + .board-conversion-overlay(class="{{#if isConverting}}active{{/if}}") + .board-conversion-modal + .board-conversion-header + h3 + | ⚙️ + | {{_ 'converting-board'}} + p {{_ 'converting-board-description'}} + + .board-conversion-content + .conversion-progress + .progress-bar + .progress-fill(style="width: {{conversionProgress}}%") + .progress-text {{conversionProgress}}% + + .conversion-status + | ⚙️ + | {{conversionStatus}} + + .conversion-time(style="{{#unless conversionEstimatedTime}}display: none;{{/unless}}") + | ⏰ + | {{_ 'estimated-time-remaining'}}: {{conversionEstimatedTime}} + + .board-conversion-footer + .conversion-info + | ℹ️ + | {{_ 'conversion-info-text'}} diff --git a/client/components/boardConversionProgress.js b/client/components/boardConversionProgress.js new file mode 100644 index 000000000..454df5006 --- /dev/null +++ b/client/components/boardConversionProgress.js @@ -0,0 +1,37 @@ +import { Template } from 'meteor/templating'; +import { ReactiveVar } from 'meteor/reactive-var'; +import { + boardConverter, + isConverting, + conversionProgress, + conversionStatus, + conversionEstimatedTime +} from '/client/lib/boardConverter'; + +Template.boardConversionProgress.helpers({ + isConverting() { + return isConverting.get(); + }, + + conversionProgress() { + return conversionProgress.get(); + }, + + conversionStatus() { + return conversionStatus.get(); + }, + + conversionEstimatedTime() { + return conversionEstimatedTime.get(); + } +}); + +Template.boardConversionProgress.onCreated(function() { + // Subscribe to conversion state changes + this.autorun(() => { + isConverting.get(); + conversionProgress.get(); + conversionStatus.get(); + conversionEstimatedTime.get(); + }); +}); diff --git a/client/components/boards/boardBody.css b/client/components/boards/boardBody.css index 32770eda6..f65cbaffc 100644 --- a/client/components/boards/boardBody.css +++ b/client/components/boards/boardBody.css @@ -269,56 +269,71 @@ } /* Mobile view styles - applied when isMiniScreen is true (iPhone, etc.) */ .board-wrapper.mobile-view { - width: 100% !important; - min-width: 100% !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; left: 0 !important; right: 0 !important; + overflow-x: hidden !important; + overflow-y: auto !important; } .board-wrapper.mobile-view .board-canvas { - width: 100% !important; - min-width: 100% !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; left: 0 !important; right: 0 !important; + overflow-x: hidden !important; + overflow-y: auto !important; } .board-wrapper.mobile-view .board-canvas.mobile-view .swimlane { border-bottom: 1px solid #ccc; - display: flex; + display: block !important; flex-direction: column; margin: 0; padding: 0; - overflow-x: hidden; + overflow-x: hidden !important; overflow-y: auto; - width: 100%; - min-width: 100%; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; } -@media screen and (max-width: 800px) { +@media screen and (max-width: 800px), + screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) { .board-wrapper { - width: 100% !important; - min-width: 100% !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; left: 0 !important; right: 0 !important; + overflow-x: hidden !important; + overflow-y: auto !important; } .board-wrapper .board-canvas { - width: 100% !important; - min-width: 100% !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; left: 0 !important; right: 0 !important; + overflow-x: hidden !important; + overflow-y: auto !important; } .board-wrapper .board-canvas .swimlane { border-bottom: 1px solid #ccc; - display: flex; + display: block !important; flex-direction: column; margin: 0; padding: 0; - overflow-x: hidden; + overflow-x: hidden !important; overflow-y: auto; - width: 100%; - min-width: 100%; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; } } .calendar-event-green { @@ -496,3 +511,10 @@ font-size: 25px; cursor: pointer; } + +/* Global file drag over state for board canvas */ +.board-canvas.file-drag-over { + background-color: rgba(0, 123, 255, 0.05) !important; + border: 2px dashed #007bff !important; + transition: all 0.2s ease; +} diff --git a/client/components/boards/boardBody.jade b/client/components/boards/boardBody.jade index 057c4bc49..d2118112b 100644 --- a/client/components/boards/boardBody.jade +++ b/client/components/boards/boardBody.jade @@ -1,5 +1,10 @@ template(name="board") - if isBoardReady.get + + if isMigrating.get + +migrationProgress + else if isConverting.get + +boardConversionProgress + else if isBoardReady.get if currentBoard if onlyShowCurrentCard +cardDetails(currentCard) @@ -16,6 +21,10 @@ template(name="boardBody") if notDisplayThisBoard | {{_ 'tableVisibilityMode-allowPrivateOnly'}} else + // Debug information (remove in production) + if debugBoardState + .debug-info(style="position: fixed; top: 0; left: 0; background: rgba(0,0,0,0.8); color: white; padding: 10px; z-index: 9999; font-size: 12px;") + | Board: {{currentBoard.title}} | View: {{boardView}} | HasSwimlanes: {{hasSwimlanes}} | Swimlanes: {{currentBoard.swimlanes.length}} .board-wrapper(class=currentBoard.colorClass class="{{#if isMiniScreen}}mobile-view{{/if}}") .board-canvas.js-swimlanes( class="{{#if hasSwimlanes}}dragscroll{{/if}}" @@ -34,15 +43,19 @@ template(name="boardBody") each currentBoard.swimlanes +swimlane(this) else - a.js-empty-board-add-swimlane(title="{{_ 'add-swimlane'}}") - h1.big-message.quiet - | {{_ 'add-swimlane'}} + + // Fallback: If no swimlanes exist, show lists instead of empty message + +listsGroup(currentBoard) else if isViewLists +listsGroup(currentBoard) else if isViewCalendar +calendarView else - +listsGroup(currentBoard) + // Default view - show swimlanes if they exist, otherwise show lists + if hasSwimlanes + each currentBoard.swimlanes + +swimlane(this) + else + +listsGroup(currentBoard) +sidebar template(name="calendarView") diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 639a75942..b0af16e43 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -1,6 +1,12 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; import dragscroll from '@wekanteam/dragscroll'; +import { boardConverter } from '/client/lib/boardConverter'; +import { migrationManager } from '/client/lib/migrationManager'; +import { attachmentMigrationManager } from '/client/lib/attachmentMigrationManager'; +import { migrationProgressManager } from '/client/components/migrationProgress'; +import Swimlanes from '/models/swimlanes'; +import Lists from '/models/lists'; const subManager = new SubsManager(); const { calculateIndex } = Utils; @@ -9,6 +15,11 @@ const swimlaneWhileSortingHeight = 150; BlazeComponent.extendComponent({ onCreated() { this.isBoardReady = new ReactiveVar(false); + this.isConverting = new ReactiveVar(false); + this.isMigrating = new ReactiveVar(false); + this._swimlaneCreated = new Set(); // Track boards where we've created swimlanes + this._boardProcessed = false; // Track if board has been processed + this._lastProcessedBoardId = null; // Track last processed board ID // The pattern we use to manually handle data loading is described here: // https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/using-subs-manager @@ -17,22 +28,512 @@ BlazeComponent.extendComponent({ this.autorun(() => { const currentBoardId = Session.get('currentBoard'); if (!currentBoardId) return; + const handle = subManager.subscribe('board', currentBoardId, false); - Tracker.nonreactive(() => { - Tracker.autorun(() => { - this.isBoardReady.set(handle.ready()); - }); + + // Use a separate autorun for subscription ready state to avoid reactive loops + this.subscriptionReadyAutorun = Tracker.autorun(() => { + if (handle.ready()) { + // Only run conversion/migration logic once per board + if (!this._boardProcessed || this._lastProcessedBoardId !== currentBoardId) { + this._boardProcessed = true; + this._lastProcessedBoardId = currentBoardId; + + // Ensure default swimlane exists (only once per board) + this.ensureDefaultSwimlane(currentBoardId); + // Check if board needs conversion + this.checkAndConvertBoard(currentBoardId); + } + } else { + this.isBoardReady.set(false); + } }); }); }, + onDestroyed() { + // Clean up the subscription ready autorun to prevent memory leaks + if (this.subscriptionReadyAutorun) { + this.subscriptionReadyAutorun.stop(); + } + }, + + ensureDefaultSwimlane(boardId) { + // Only create swimlane once per board + if (this._swimlaneCreated.has(boardId)) { + return; + } + + try { + const board = ReactiveCache.getBoard(boardId); + if (!board) return; + + const swimlanes = board.swimlanes(); + + if (swimlanes.length === 0) { + // Check if any swimlane exists in the database to avoid race conditions + const existingSwimlanes = ReactiveCache.getSwimlanes({ boardId }); + if (existingSwimlanes.length === 0) { + const swimlaneId = Swimlanes.insert({ + title: 'Default', + boardId: boardId, + }); + if (process.env.DEBUG === 'true') { + console.log(`Created default swimlane ${swimlaneId} for board ${boardId}`); + } + } + this._swimlaneCreated.add(boardId); + } else { + this._swimlaneCreated.add(boardId); + } + } catch (error) { + console.error('Error creating default swimlane:', error); + } + }, + + async checkAndConvertBoard(boardId) { + try { + const board = ReactiveCache.getBoard(boardId); + if (!board) { + this.isBoardReady.set(true); + return; + } + + // Automatic migration disabled - migrations must be run manually from sidebar + // Board admins can run migrations from the sidebar Migrations menu + this.isBoardReady.set(true); + + } catch (error) { + console.error('Error during board conversion check:', error); + this.isConverting.set(false); + this.isMigrating.set(false); + this.isBoardReady.set(true); // Show board even if conversion check failed + } + }, + + /** + * Check if board needs comprehensive migration + */ + async checkComprehensiveMigration(boardId) { + try { + return new Promise((resolve, reject) => { + Meteor.call('comprehensiveBoardMigration.needsMigration', boardId, (error, result) => { + if (error) { + console.error('Error checking comprehensive migration:', error); + reject(error); + } else { + resolve(result); + } + }); + }); + } catch (error) { + console.error('Error checking comprehensive migration:', error); + return false; + } + }, + + /** + * Execute comprehensive migration for a board + */ + async executeComprehensiveMigration(boardId) { + try { + // Start progress tracking + migrationProgressManager.startMigration(); + + // Simulate progress updates since we can't easily pass callbacks through Meteor methods + const progressSteps = [ + { step: 'analyze_board_structure', name: 'Analyze Board Structure', duration: 1000 }, + { step: 'fix_orphaned_cards', name: 'Fix Orphaned Cards', duration: 2000 }, + { step: 'convert_shared_lists', name: 'Convert Shared Lists', duration: 3000 }, + { step: 'ensure_per_swimlane_lists', name: 'Ensure Per-Swimlane Lists', duration: 1500 }, + { step: 'validate_migration', name: 'Validate Migration', duration: 1000 }, + { step: 'fix_avatar_urls', name: 'Fix Avatar URLs', duration: 1000 }, + { step: 'fix_attachment_urls', name: 'Fix Attachment URLs', duration: 1000 } + ]; + + // Start the actual migration + const migrationPromise = new Promise((resolve, reject) => { + Meteor.call('comprehensiveBoardMigration.execute', boardId, (error, result) => { + if (error) { + console.error('Error executing comprehensive migration:', error); + migrationProgressManager.failMigration(error); + reject(error); + } else { + if (process.env.DEBUG === 'true') { + console.log('Comprehensive migration completed for board:', boardId, result); + } + resolve(result.success); + } + }); + }); + + // Simulate progress updates + const progressPromise = this.simulateMigrationProgress(progressSteps); + + // Wait for both to complete + const [migrationResult] = await Promise.all([migrationPromise, progressPromise]); + + migrationProgressManager.completeMigration(); + return migrationResult; + + } catch (error) { + console.error('Error executing comprehensive migration:', error); + migrationProgressManager.failMigration(error); + return false; + } + }, + + /** + * Simulate migration progress updates + */ + async simulateMigrationProgress(progressSteps) { + const totalSteps = progressSteps.length; + + for (let i = 0; i < progressSteps.length; i++) { + const step = progressSteps[i]; + const stepProgress = Math.round(((i + 1) / totalSteps) * 100); + + // Update progress for this step + migrationProgressManager.updateProgress({ + overallProgress: stepProgress, + currentStep: i + 1, + totalSteps, + stepName: step.step, + stepProgress: 0, + stepStatus: `Starting ${step.name}...`, + stepDetails: null, + boardId: Session.get('currentBoard') + }); + + // Simulate step progress + const stepDuration = step.duration; + const updateInterval = 100; // Update every 100ms + const totalUpdates = stepDuration / updateInterval; + + for (let j = 0; j < totalUpdates; j++) { + const stepStepProgress = Math.round(((j + 1) / totalUpdates) * 100); + + migrationProgressManager.updateProgress({ + overallProgress: stepProgress, + currentStep: i + 1, + totalSteps, + stepName: step.step, + stepProgress: stepStepProgress, + stepStatus: `Processing ${step.name}...`, + stepDetails: { progress: `${stepStepProgress}%` }, + boardId: Session.get('currentBoard') + }); + + await new Promise(resolve => setTimeout(resolve, updateInterval)); + } + + // Complete the step + migrationProgressManager.updateProgress({ + overallProgress: stepProgress, + currentStep: i + 1, + totalSteps, + stepName: step.step, + stepProgress: 100, + stepStatus: `${step.name} completed`, + stepDetails: { status: 'completed' }, + boardId: Session.get('currentBoard') + }); + } + }, + + async startBackgroundMigration(boardId) { + try { + // Start background migration using the cron system + Meteor.call('boardMigration.startBoardMigration', boardId, (error, result) => { + if (error) { + console.error('Failed to start background migration:', error); + } else { + if (process.env.DEBUG === 'true') { + console.log('Background migration started for board:', boardId); + } + } + }); + } catch (error) { + console.error('Error starting background migration:', error); + } + }, + + async convertSharedListsToPerSwimlane(boardId) { + try { + const board = ReactiveCache.getBoard(boardId); + if (!board) return; + + // Check if board has already been processed for shared lists conversion + if (board.hasSharedListsConverted) { + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has already been processed for shared lists conversion`); + } + return; + } + + // Get all lists for this board + const allLists = board.lists(); + const swimlanes = board.swimlanes(); + + if (swimlanes.length === 0) { + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has no swimlanes, skipping shared lists conversion`); + } + return; + } + + // Find shared lists (lists with empty swimlaneId or null swimlaneId) + const sharedLists = allLists.filter(list => !list.swimlaneId || list.swimlaneId === ''); + + if (sharedLists.length === 0) { + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has no shared lists to convert`); + } + // Mark as processed even if no shared lists + Boards.update(boardId, { $set: { hasSharedListsConverted: true } }); + return; + } + + if (process.env.DEBUG === 'true') { + console.log(`Converting ${sharedLists.length} shared lists to per-swimlane lists for board ${boardId}`); + } + + // Convert each shared list to per-swimlane lists + for (const sharedList of sharedLists) { + // Create a copy of the list for each swimlane + for (const swimlane of swimlanes) { + // Check if this list already exists in this swimlane + const existingList = Lists.findOne({ + boardId: boardId, + swimlaneId: swimlane._id, + title: sharedList.title + }); + + if (!existingList) { + // Double-check to avoid race conditions + const doubleCheckList = ReactiveCache.getList({ + boardId: boardId, + swimlaneId: swimlane._id, + title: sharedList.title + }); + + if (!doubleCheckList) { + // Create a new list in this swimlane + const newListData = { + title: sharedList.title, + boardId: boardId, + swimlaneId: swimlane._id, + sort: sharedList.sort || 0, + archived: sharedList.archived || false, // Preserve archived state from original list + createdAt: new Date(), + modifiedAt: new Date() + }; + + // Copy other properties if they exist + if (sharedList.color) newListData.color = sharedList.color; + if (sharedList.wipLimit) newListData.wipLimit = sharedList.wipLimit; + if (sharedList.wipLimitEnabled) newListData.wipLimitEnabled = sharedList.wipLimitEnabled; + if (sharedList.wipLimitSoft) newListData.wipLimitSoft = sharedList.wipLimitSoft; + + Lists.insert(newListData); + + if (process.env.DEBUG === 'true') { + const archivedStatus = sharedList.archived ? ' (archived)' : ' (active)'; + console.log(`Created list "${sharedList.title}"${archivedStatus} for swimlane ${swimlane.title || swimlane._id}`); + } + } else { + if (process.env.DEBUG === 'true') { + console.log(`List "${sharedList.title}" already exists in swimlane ${swimlane.title || swimlane._id} (double-check), skipping`); + } + } + } else { + if (process.env.DEBUG === 'true') { + console.log(`List "${sharedList.title}" already exists in swimlane ${swimlane.title || swimlane._id}, skipping`); + } + } + } + + // Remove the original shared list completely + Lists.remove(sharedList._id); + + if (process.env.DEBUG === 'true') { + console.log(`Removed shared list "${sharedList.title}"`); + } + } + + // Mark board as processed + Boards.update(boardId, { $set: { hasSharedListsConverted: true } }); + + if (process.env.DEBUG === 'true') { + console.log(`Successfully converted ${sharedLists.length} shared lists to per-swimlane lists for board ${boardId}`); + } + + } catch (error) { + console.error('Error converting shared lists to per-swimlane:', error); + } + }, + + async fixMissingLists(boardId) { + try { + const board = ReactiveCache.getBoard(boardId); + if (!board) return; + + // Check if board has already been processed for missing lists fix + if (board.fixMissingListsCompleted) { + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has already been processed for missing lists fix`); + } + return; + } + + // Check if migration is needed + const needsMigration = await new Promise((resolve, reject) => { + Meteor.call('fixMissingListsMigration.needsMigration', boardId, (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + }); + + if (!needsMigration) { + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} does not need missing lists fix`); + } + return; + } + + if (process.env.DEBUG === 'true') { + console.log(`Starting fix missing lists migration for board ${boardId}`); + } + + // Execute the migration + const result = await new Promise((resolve, reject) => { + Meteor.call('fixMissingListsMigration.execute', boardId, (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + }); + + if (result && result.success) { + if (process.env.DEBUG === 'true') { + console.log(`Successfully fixed missing lists for board ${boardId}: created ${result.createdLists} lists, updated ${result.updatedCards} cards`); + } + } + + } catch (error) { + console.error('Error fixing missing lists:', error); + } + }, + + async fixDuplicateLists(boardId) { + try { + const board = ReactiveCache.getBoard(boardId); + if (!board) return; + + // Check if board has already been processed for duplicate lists fix + if (board.fixDuplicateListsCompleted) { + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has already been processed for duplicate lists fix`); + } + return; + } + + if (process.env.DEBUG === 'true') { + console.log(`Starting duplicate lists fix for board ${boardId}`); + } + + // Execute the duplicate lists fix + const result = await new Promise((resolve, reject) => { + Meteor.call('fixDuplicateLists.fixBoard', boardId, (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + }); + + if (result && result.fixed > 0) { + if (process.env.DEBUG === 'true') { + console.log(`Successfully fixed ${result.fixed} duplicate lists for board ${boardId}: ${result.fixedSwimlanes} swimlanes, ${result.fixedLists} lists`); + } + + // Mark board as processed + Boards.update(boardId, { $set: { fixDuplicateListsCompleted: true } }); + } else if (process.env.DEBUG === 'true') { + console.log(`No duplicate lists found for board ${boardId}`); + // Still mark as processed to avoid repeated checks + Boards.update(boardId, { $set: { fixDuplicateListsCompleted: true } }); + } else { + // Still mark as processed to avoid repeated checks + Boards.update(boardId, { $set: { fixDuplicateListsCompleted: true } }); + } + + } catch (error) { + console.error('Error fixing duplicate lists:', error); + } + }, + + async startAttachmentMigrationIfNeeded(boardId) { + try { + // Check if board has already been migrated + if (attachmentMigrationManager.isBoardMigrated(boardId)) { + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has already been migrated, skipping`); + } + return; + } + + // Check if there are unconverted attachments + const unconvertedAttachments = attachmentMigrationManager.getUnconvertedAttachments(boardId); + + if (unconvertedAttachments.length > 0) { + if (process.env.DEBUG === 'true') { + console.log(`Starting attachment migration for ${unconvertedAttachments.length} attachments in board ${boardId}`); + } + await attachmentMigrationManager.startAttachmentMigration(boardId); + } else { + // No attachments to migrate, mark board as migrated + // This will be handled by the migration manager itself + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has no attachments to migrate`); + } + } + } catch (error) { + console.error('Error starting attachment migration:', error); + } + }, + onlyShowCurrentCard() { - return Utils.isMiniScreen() && Utils.getCurrentCardId(true); + const isMiniScreen = Utils.isMiniScreen(); + const currentCardId = Utils.getCurrentCardId(true); + return isMiniScreen && currentCardId; }, goHome() { FlowRouter.go('home'); }, + + isConverting() { + return this.isConverting.get(); + }, + + isMigrating() { + return this.isMigrating.get(); + }, + + isBoardReady() { + return this.isBoardReady.get(); + }, + + currentBoard() { + return Utils.getCurrentBoard(); + }, }).register('board'); BlazeComponent.extendComponent({ @@ -43,36 +544,51 @@ BlazeComponent.extendComponent({ this._isDragging = false; // Used to set the overlay this.mouseHasEnterCardDetails = false; + this._sortFieldsFixed = new Set(); // Track which boards have had sort fields fixed // fix swimlanes sort field if there are null values const currentBoardData = Utils.getCurrentBoard(); - const nullSortSwimlanes = currentBoardData.nullSortSwimlanes(); - if (nullSortSwimlanes.length > 0) { - const swimlanes = currentBoardData.swimlanes(); - let count = 0; - swimlanes.forEach(s => { - Swimlanes.update(s._id, { - $set: { - sort: count, - }, - }); - count += 1; - }); + if (currentBoardData && Swimlanes) { + const boardId = currentBoardData._id; + // Only fix sort fields once per board to prevent reactive loops + if (!this._sortFieldsFixed.has(`swimlanes-${boardId}`)) { + const nullSortSwimlanes = currentBoardData.nullSortSwimlanes(); + if (nullSortSwimlanes.length > 0) { + const swimlanes = currentBoardData.swimlanes(); + let count = 0; + swimlanes.forEach(s => { + Swimlanes.update(s._id, { + $set: { + sort: count, + }, + }); + count += 1; + }); + } + this._sortFieldsFixed.add(`swimlanes-${boardId}`); + } } // fix lists sort field if there are null values - const nullSortLists = currentBoardData.nullSortLists(); - if (nullSortLists.length > 0) { - const lists = currentBoardData.lists(); - let count = 0; - lists.forEach(l => { - Lists.update(l._id, { - $set: { - sort: count, - }, - }); - count += 1; - }); + if (currentBoardData && Lists) { + const boardId = currentBoardData._id; + // Only fix sort fields once per board to prevent reactive loops + if (!this._sortFieldsFixed.has(`lists-${boardId}`)) { + const nullSortLists = currentBoardData.nullSortLists(); + if (nullSortLists.length > 0) { + const lists = currentBoardData.lists(); + let count = 0; + lists.forEach(l => { + Lists.update(l._id, { + $set: { + sort: count, + }, + }); + count += 1; + }); + } + this._sortFieldsFixed.add(`lists-${boardId}`); + } } }, onRendered() { @@ -98,11 +614,16 @@ BlazeComponent.extendComponent({ } } - // Observe for new popups/menus and set focus + // Observe for new popups/menus and set focus (but exclude swimlane content) const popupObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { mutation.addedNodes.forEach(function(node) { - if (node.nodeType === 1 && (node.classList.contains('popup') || node.classList.contains('modal') || node.classList.contains('menu'))) { + if (node.nodeType === 1 && + (node.classList.contains('popup') || node.classList.contains('modal') || node.classList.contains('menu')) && + !node.closest('.js-swimlanes') && + !node.closest('.swimlane') && + !node.closest('.list') && + !node.closest('.minicard')) { setTimeout(function() { focusFirstInteractive(node); }, 10); } }); @@ -380,22 +901,20 @@ BlazeComponent.extendComponent({ // Always reset dragscroll on view switch dragscroll.reset(); - if (Utils.isTouchScreenOrShowDesktopDragHandles()) { - $swimlanesDom.sortable({ - handle: '.js-swimlane-header-handle', - }); - } else { - $swimlanesDom.sortable({ - handle: '.swimlane-header', - }); - } + if ($swimlanesDom.data('uiSortable') || $swimlanesDom.data('sortable')) { + if (Utils.isTouchScreenOrShowDesktopDragHandles()) { + $swimlanesDom.sortable('option', 'handle', '.js-swimlane-header-handle'); + } else { + $swimlanesDom.sortable('option', 'handle', '.swimlane-header'); + } - // Disable drag-dropping if the current user is not a board member - $swimlanesDom.sortable( - 'option', - 'disabled', - !ReactiveCache.getCurrentUser()?.isBoardAdmin(), - ); + // Disable drag-dropping if the current user is not a board member + $swimlanesDom.sortable( + 'option', + 'disabled', + !ReactiveCache.getCurrentUser()?.isBoardAdmin(), + ); + } }); // If there is no data in the board (ie, no lists) we autofocus the list @@ -412,51 +931,122 @@ BlazeComponent.extendComponent({ notDisplayThisBoard() { let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly'); let currentBoard = Utils.getCurrentBoard(); - if (allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue && currentBoard.permission == 'public') { - return true; - } - - return false; + return allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue && currentBoard && currentBoard.permission == 'public'; }, isViewSwimlanes() { const currentUser = ReactiveCache.getCurrentUser(); + let boardView; + if (currentUser) { - return (currentUser.profile || {}).boardView === 'board-view-swimlanes'; + boardView = (currentUser.profile || {}).boardView; } else { - return ( - window.localStorage.getItem('boardView') === 'board-view-swimlanes' - ); + boardView = window.localStorage.getItem('boardView'); } - }, - - hasSwimlanes() { - return Utils.getCurrentBoard().swimlanes().length > 0; + + // If no board view is set, default to swimlanes + if (!boardView) { + boardView = 'board-view-swimlanes'; + } + + return boardView === 'board-view-swimlanes'; }, isViewLists() { const currentUser = ReactiveCache.getCurrentUser(); + let boardView; + if (currentUser) { - return (currentUser.profile || {}).boardView === 'board-view-lists'; + boardView = (currentUser.profile || {}).boardView; } else { - return window.localStorage.getItem('boardView') === 'board-view-lists'; + boardView = window.localStorage.getItem('boardView'); } + + return boardView === 'board-view-lists'; }, isViewCalendar() { const currentUser = ReactiveCache.getCurrentUser(); + let boardView; + if (currentUser) { - return (currentUser.profile || {}).boardView === 'board-view-cal'; + boardView = (currentUser.profile || {}).boardView; } else { - return window.localStorage.getItem('boardView') === 'board-view-cal'; + boardView = window.localStorage.getItem('boardView'); + } + + return boardView === 'board-view-cal'; + }, + + hasSwimlanes() { + const currentBoard = Utils.getCurrentBoard(); + if (!currentBoard) { + if (process.env.DEBUG === 'true') { + console.log('hasSwimlanes: No current board'); + } + return false; + } + + try { + const swimlanes = currentBoard.swimlanes(); + const hasSwimlanes = swimlanes && swimlanes.length > 0; + if (process.env.DEBUG === 'true') { + console.log('hasSwimlanes: Board has', swimlanes ? swimlanes.length : 0, 'swimlanes'); + } + return hasSwimlanes; + } catch (error) { + console.error('hasSwimlanes: Error getting swimlanes:', error); + return false; } }, + isVerticalScrollbars() { const user = ReactiveCache.getCurrentUser(); return user && user.isVerticalScrollbars(); }, + boardView() { + return Utils.boardView(); + }, + + debugBoardState() { + // Enable debug mode by setting ?debug=1 in URL + const urlParams = new URLSearchParams(window.location.search); + return urlParams.get('debug') === '1'; + }, + + debugBoardStateData() { + const currentBoard = Utils.getCurrentBoard(); + const currentBoardId = Session.get('currentBoard'); + const isBoardReady = this.isBoardReady.get(); + const isConverting = this.isConverting.get(); + const isMigrating = this.isMigrating.get(); + const boardView = Utils.boardView(); + + if (process.env.DEBUG === 'true') { + console.log('=== BOARD DEBUG STATE ==='); + console.log('currentBoardId:', currentBoardId); + console.log('currentBoard:', !!currentBoard, currentBoard ? currentBoard.title : 'none'); + console.log('isBoardReady:', isBoardReady); + console.log('isConverting:', isConverting); + console.log('isMigrating:', isMigrating); + console.log('boardView:', boardView); + console.log('========================'); + } + + return { + currentBoardId, + hasCurrentBoard: !!currentBoard, + currentBoardTitle: currentBoard ? currentBoard.title : 'none', + isBoardReady, + isConverting, + isMigrating, + boardView + }; + }, + + openNewListForm() { if (this.isViewSwimlanes()) { // The form had been removed in 416b17062e57f215206e93a85b02ef9eb1ab4902 @@ -480,6 +1070,31 @@ BlazeComponent.extendComponent({ } }, 'click .js-empty-board-add-swimlane': Popup.open('swimlaneAdd'), + // Global drag and drop file upload handlers for better visual feedback + 'dragover .board-canvas'(event) { + const dataTransfer = event.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + // Add visual indicator that files can be dropped + $('.board-canvas').addClass('file-drag-over'); + } + }, + 'dragleave .board-canvas'(event) { + const dataTransfer = event.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + // Only remove class if we're leaving the board canvas entirely + if (!event.currentTarget.contains(event.relatedTarget)) { + $('.board-canvas').removeClass('file-drag-over'); + } + } + }, + 'drop .board-canvas'(event) { + const dataTransfer = event.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + $('.board-canvas').removeClass('file-drag-over'); + } + }, }, ]; }, @@ -756,9 +1371,13 @@ BlazeComponent.extendComponent({ const firstSwimlane = currentBoard.swimlanes()[0]; Meteor.call('createCardWithDueDate', currentBoard._id, firstList._id, myTitle, startDate.toDate(), firstSwimlane._id, function(error, result) { if (error) { - console.log(error); + if (process.env.DEBUG === 'true') { + console.log(error); + } } else { - console.log("Card Created", result); + if (process.env.DEBUG === 'true') { + console.log("Card Created", result); + } } }); closeModal(); diff --git a/client/components/boards/boardHeader.css b/client/components/boards/boardHeader.css index f3cb652e7..faf20e2f5 100644 --- a/client/components/boards/boardHeader.css +++ b/client/components/boards/boardHeader.css @@ -505,73 +505,73 @@ flex-wrap: nowrap !important; align-items: stretch !important; justify-content: flex-start !important; - width: 100% !important; - max-width: 100% !important; - min-width: 100% !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; overflow-x: hidden !important; overflow-y: auto !important; } -.mobile-mode .swimlane { - display: block !important; - width: 100% !important; - max-width: 100% !important; - min-width: 100% !important; - margin: 0 0 2rem 0 !important; - padding: 0 !important; - float: none !important; - clear: both !important; -} + .mobile-mode .swimlane { + display: block !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; + margin: 0 0 2rem 0 !important; + padding: 0 !important; + float: none !important; + clear: both !important; + } -.mobile-mode .swimlane .swimlane-header { - display: block !important; - width: 100% !important; - max-width: 100% !important; - min-width: 100% !important; - margin: 0 0 1rem 0 !important; - padding: 1rem !important; - font-size: clamp(18px, 2.5vw, 32px) !important; - font-weight: bold !important; - border-bottom: 2px solid #ccc !important; -} + .mobile-mode .swimlane .swimlane-header { + display: block !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; + margin: 0 0 1rem 0 !important; + padding: 1rem !important; + font-size: clamp(18px, 2.5vw, 32px) !important; + font-weight: bold !important; + border-bottom: 2px solid #ccc !important; + } -.mobile-mode .swimlane .lists { - display: block !important; - width: 100% !important; - max-width: 100% !important; - min-width: 100% !important; - margin: 0 !important; - padding: 0 !important; - flex-direction: column !important; - flex-wrap: nowrap !important; - align-items: stretch !important; - justify-content: flex-start !important; -} + .mobile-mode .swimlane .lists { + display: block !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; + margin: 0 !important; + padding: 0 !important; + flex-direction: column !important; + flex-wrap: nowrap !important; + align-items: stretch !important; + justify-content: flex-start !important; + } -.mobile-mode .list { - display: block !important; - width: 100% !important; - max-width: 100% !important; - min-width: 100% !important; - margin: 0 0 2rem 0 !important; - padding: 0 !important; - float: none !important; - clear: both !important; - border-left: none !important; - border-right: none !important; - border-top: none !important; - border-bottom: 2px solid #ccc !important; - flex: none !important; - flex-basis: auto !important; - flex-grow: 0 !important; - flex-shrink: 0 !important; - position: static !important; - left: auto !important; - right: auto !important; - top: auto !important; - bottom: auto !important; - transform: none !important; -} + .mobile-mode .list { + display: block !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; + margin: 0 0 2rem 0 !important; + padding: 0 !important; + float: none !important; + clear: both !important; + border-left: none !important; + border-right: none !important; + border-top: none !important; + border-bottom: 2px solid #ccc !important; + flex: none !important; + flex-basis: auto !important; + flex-grow: 0 !important; + flex-shrink: 0 !important; + position: static !important; + left: auto !important; + right: auto !important; + top: auto !important; + bottom: auto !important; + transform: none !important; + } .mobile-mode .list:first-child { margin-left: 0 !important; @@ -667,9 +667,9 @@ flex-wrap: nowrap !important; align-items: stretch !important; justify-content: flex-start !important; - width: 100% !important; - max-width: 100% !important; - min-width: 100% !important; + width: 100vw !important; + max-width: 100vw !important; + min-width: 100vw !important; overflow-x: hidden !important; overflow-y: auto !important; } diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index 740696c0f..bac4216ed 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -14,41 +14,41 @@ template(name="boardHeaderBar") with currentBoard if currentUser.isBoardAdmin a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title) - i.fa.fa-pencil-square-o + | ✏️ - a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}" - title="{{#if isStarred}}{{_ 'star-board-short-unstar'}}{{else}}{{_ 'star-board-short-star'}}{{/if}}" aria-label="{{#if isStarred}}{{_ 'star-board-short-unstar'}}{{else}}{{_ 'star-board-short-star'}}{{/if}}") - i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}") - if showStarCounter - span - = currentBoard.stars + a.board-header-btn( + class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}" + title="{{_ currentBoard.permission}}") + | {{#if currentBoard.isPublic}}🌐{{else}}🔒{{/if}} + span {{_ currentBoard.permission}} - a.board-header-btn( - class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}" - title="{{_ currentBoard.permission}}") - i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}") - span {{_ currentBoard.permission}} - - a.board-header-btn.js-watch-board( - title="{{_ watchLevel }}") - if $eq watchLevel "watching" - i.fa.fa-eye - if $eq watchLevel "tracking" - i.fa.fa-bell - if $eq watchLevel "muted" - i.fa.fa-bell-slash - span {{_ watchLevel}} - a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}") - i.fa.fa-sort - span {{#if isSortActive }}{{_ 'sort-is-on'}}{{else}}{{_ 'sort-cards'}}{{/if}} + a.board-header-btn.js-watch-board( + title="{{_ watchLevel }}") + if $eq watchLevel "watching" + | 👁️ + if $eq watchLevel "tracking" + | 🔔 + if $eq watchLevel "muted" + | 🔕 + span {{_ watchLevel}} + a.board-header-btn.js-star-board(title="{{_ 'star-board'}}") + if isStarred + | ⭐ + else + | ☆ + if showStarCounter + span.board-star-counter {{currentBoard.stars}} + a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}") + | {{sortCardsIcon}} + span {{#if isSortActive }}{{_ 'sort-is-on'}}{{else}}{{_ 'sort-cards'}}{{/if}} if isSortActive a.board-header-btn-close.js-sort-reset(title="{{_ 'remove-sort'}}") - i.fa.fa-times-thin + | ❌ else a.board-header-btn.js-log-in( title="{{_ 'log-in'}}") - i.fa.fa-sign-in + | 🚪 span {{_ 'log-in'}} .board-header-btns.center @@ -59,40 +59,41 @@ template(name="boardHeaderBar") if currentUser with currentBoard a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title) - i.fa.fa-pencil-square-o + | ✏️ - a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}" - title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}") - i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}") + a.board-header-btn( + class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}" + title="{{_ currentBoard.permission}}") + | {{#if currentBoard.isPublic}}🌐{{else}}🔒{{/if}} - a.board-header-btn( - class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}" - title="{{_ currentBoard.permission}}") - i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}") - - a.board-header-btn.js-watch-board( - title="{{_ watchLevel }}") - if $eq watchLevel "watching" - i.fa.fa-eye - if $eq watchLevel "tracking" - i.fa.fa-bell - if $eq watchLevel "muted" - i.fa.fa-bell-slash - a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}") - i.fa.fa-sort + a.board-header-btn.js-watch-board( + title="{{_ watchLevel }}") + if $eq watchLevel "watching" + | 👁️ + if $eq watchLevel "tracking" + | 🔔 + if $eq watchLevel "muted" + | 🔕 + a.board-header-btn.js-star-board(title="{{_ 'star-board'}}") + if isStarred + | ⭐ + else + | ☆ + a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}") + | {{sortCardsIcon}} if isSortActive a.board-header-btn-close.js-sort-reset(title="{{_ 'remove-sort'}}") - i.fa.fa-times-thin + | ❌ else a.board-header-btn.js-log-in( title="{{_ 'log-in'}}") - i.fa.fa-sign-in + | 🚪 if isSandstorm if currentUser a.board-header-btn.js-open-archived-board - i.fa.fa-archive + | 📦 //if showSort // a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}") @@ -102,56 +103,56 @@ template(name="boardHeaderBar") a.board-header-btn.js-open-filter-view( title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}" class="{{#if Filter.isActive}}emphasis{{/if}}") - i.fa.fa-filter + | 🔽 if Filter.isActive a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}") - i.fa.fa-times-thin + | ❌ a.board-header-btn.js-open-search-view(title="{{_ 'search'}}") - i.fa.fa-search + | 🔍 unless currentBoard.isTemplatesBoard a.board-header-btn.js-toggle-board-view( title="{{_ 'board-view'}}") - i.fa.fa-caret-down + | ▼ if $eq boardView 'board-view-swimlanes' - i.fa.fa-th-large + | 🏊 if $eq boardView 'board-view-lists' - i.fa.fa-trello + | 📋 if $eq boardView 'board-view-cal' - i.fa.fa-calendar + | 📅 if canModifyBoard a.board-header-btn.js-multiselection-activate( title="{{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}" class="{{#if MultiSelection.isActive}}emphasis{{/if}}") - i.fa.fa-check-square-o - if MultiSelection.isActive - a.board-header-btn-close.js-multiselection-reset(title="{{_ 'filter-clear'}}") - i.fa.fa-times-thin + | ☑️ + if MultiSelection.isActive + a.board-header-btn-close.js-multiselection-reset(title="{{_ 'filter-clear'}}") + | ❌ .separator a.board-header-btn.js-toggle-sidebar(title="{{_ 'sidebar-open'}} {{_ 'or'}} {{_ 'sidebar-close'}}") - i.fa.fa-navicon + | ☰ template(name="boardVisibilityList") ul.pop-over-list li with "private" a.js-select-visibility - i.fa.fa-lock.colorful + | 🔒 | {{_ 'private'}} if visibilityCheck - i.fa.fa-check + | ✅ span.sub-name {{_ 'private-desc'}} if notAllowPrivateVisibilityOnly li with "public" a.js-select-visibility - i.fa.fa-globe.colorful + | 🌐 | {{_ 'public'}} if visibilityCheck - i.fa.fa-check + | ✅ span.sub-name {{_ 'public-desc'}} template(name="boardChangeVisibilityPopup") @@ -162,26 +163,26 @@ template(name="boardChangeWatchPopup") li with "watching" a.js-select-watch - i.fa.fa-eye.colorful + | 👁️ | {{_ 'watching'}} if watchCheck - i.fa.fa-check + | ✅ span.sub-name {{_ 'watching-info'}} li with "tracking" a.js-select-watch - i.fa.fa-bell.colorful + | 🔔 | {{_ 'tracking'}} if watchCheck - i.fa.fa-check + | ✅ span.sub-name {{_ 'tracking-info'}} li with "muted" a.js-select-watch - i.fa.fa-bell-slash.colorful + | 🔕 | {{_ 'muted'}} if watchCheck - i.fa.fa-check + | ✅ span.sub-name {{_ 'muted-info'}} template(name="boardChangeViewPopup") @@ -189,24 +190,24 @@ template(name="boardChangeViewPopup") li with "board-view-swimlanes" a.js-open-swimlanes-view - i.fa.fa-th-large.colorful + | 🏊 | {{_ 'board-view-swimlanes'}} if $eq Utils.boardView "board-view-swimlanes" - i.fa.fa-check + | ✅ li with "board-view-lists" a.js-open-lists-view - i.fa.fa-trello.colorful + | 📋 | {{_ 'board-view-lists'}} if $eq Utils.boardView "board-view-lists" - i.fa.fa-check + | ✅ li with "board-view-cal" a.js-open-cal-view - i.fa.fa-calendar.colorful + | 📅 | {{_ 'board-view-cal'}} if $eq Utils.boardView "board-view-cal" - i.fa.fa-check + | ✅ template(name="createBoard") form @@ -218,11 +219,70 @@ template(name="createBoard") else p.quiet if $eq visibility.get 'public' - span.fa.fa-globe.colorful + span 🌐 = " " | {{{_ 'board-public-info'}}} else - span.fa.fa-lock.colorful + span 🔒 + = " " + | {{{_ 'board-private-info'}}} + a.js-change-visibility {{_ 'change'}}. + a.flex.js-toggle-add-template-container + .materialCheckBox#add-template-container + span {{_ 'add-template-container'}} + input.primary.wide(type="submit" value="{{_ 'create'}}") + span.quiet + | {{_ 'or'}} + a.js-import-board {{_ 'import'}} + span.quiet + | / + a.js-board-template {{_ 'template'}} + +template(name="createBoardPopup") + form + label + | {{_ 'title'}} + input.js-new-board-title(type="text" placeholder="{{_ 'bucket-example'}}" autofocus required) + if visibilityMenuIsOpen.get + +boardVisibilityList + else + p.quiet + if $eq visibility.get 'public' + span 🌐 + = " " + | {{{_ 'board-public-info'}}} + else + span 🔒 + = " " + | {{{_ 'board-private-info'}}} + a.js-change-visibility {{_ 'change'}}. + a.flex.js-toggle-add-template-container + .materialCheckBox#add-template-container + span {{_ 'add-template-container'}} + input.primary.wide(type="submit" value="{{_ 'create'}}") + span.quiet + | {{_ 'or'}} + a.js-import-board {{_ 'import'}} + span.quiet + | / + a.js-board-template {{_ 'template'}} + +// New popup for Template Container creation; shares the same form content +template(name="createTemplateContainerPopup") + form + label + | {{_ 'title'}} + input.js-new-board-title(type="text" placeholder="{{_ 'bucket-example'}}" autofocus required) + if visibilityMenuIsOpen.get + +boardVisibilityList + else + p.quiet + if $eq visibility.get 'public' + span 🌐 + = " " + | {{{_ 'board-public-info'}}} + else + span 🔒 = " " | {{{_ 'board-private-info'}}} a.js-change-visibility {{_ 'change'}}. @@ -246,10 +306,10 @@ template(name="createBoard") // li // a.js-sort-by(name="{{value.name}}") // if $eq sortby value.name -// i(class="fa {{Direction}}") +// | {{#if $eq Direction "fa-arrow-up"}}⬆️{{else}}⬇️{{/if}} // | {{_ value.label }}{{_ value.shortLabel}} // if $eq sortby value.name -// i(class="fa fa-check") +// | ✅ template(name="boardChangeTitlePopup") form @@ -269,14 +329,22 @@ template(name="boardCreateRulePopup") template(name="cardsSortPopup") ul.pop-over-list li - a.js-sort-due {{_ 'due-date'}} + a.js-sort-due + | 📅 + | {{_ 'due-date'}} hr li - a.js-sort-title {{_ 'title-alphabetically'}} + a.js-sort-title + | 🔤 + | {{_ 'title-alphabetically'}} hr li - a.js-sort-created-desc {{_ 'created-at-newest-first'}} + a.js-sort-created-desc + | ⬇️ + | {{_ 'created-at-newest-first'}} hr li - a.js-sort-created-asc {{_ 'created-at-oldest-first'}} + a.js-sort-created-asc + | ⬆️ + | {{_ 'created-at-oldest-first'}} diff --git a/client/components/boards/boardHeader.js b/client/components/boards/boardHeader.js index 5d54c2dd3..c84b593c6 100644 --- a/client/components/boards/boardHeader.js +++ b/client/components/boards/boardHeader.js @@ -72,7 +72,10 @@ BlazeComponent.extendComponent({ { 'click .js-edit-board-title': Popup.open('boardChangeTitle'), 'click .js-star-board'() { - ReactiveCache.getCurrentUser().toggleBoardStar(Session.get('currentBoard')); + const boardId = Session.get('currentBoard'); + if (boardId) { + Meteor.call('toggleBoardStar', boardId); + } }, 'click .js-open-board-menu': Popup.open('boardMenu'), 'click .js-change-visibility': Popup.open('boardChangeVisibility'), @@ -82,10 +85,37 @@ BlazeComponent.extendComponent({ }, 'click .js-toggle-board-view': Popup.open('boardChangeView'), 'click .js-toggle-sidebar'() { - Sidebar.toggle(); + if (process.env.DEBUG === 'true') { + console.log('Hamburger menu clicked'); + } + // Use the same approach as keyboard shortcuts + if (typeof Sidebar !== 'undefined' && Sidebar && typeof Sidebar.toggle === 'function') { + if (process.env.DEBUG === 'true') { + console.log('Using Sidebar.toggle()'); + } + Sidebar.toggle(); + } else { + if (process.env.DEBUG === 'true') { + console.warn('Sidebar not available, trying alternative approach'); + } + // Try to trigger the sidebar through the global Blaze helper + if (typeof Blaze !== 'undefined' && Blaze._globalHelpers && Blaze._globalHelpers.Sidebar) { + const sidebar = Blaze._globalHelpers.Sidebar(); + if (sidebar && typeof sidebar.toggle === 'function') { + if (process.env.DEBUG === 'true') { + console.log('Using Blaze helper Sidebar.toggle()'); + } + sidebar.toggle(); + } + } + } }, 'click .js-open-filter-view'() { - Sidebar.setView('filter'); + if (Sidebar) { + Sidebar.setView('filter'); + } else { + console.warn('Sidebar not available for setView'); + } }, 'click .js-sort-cards': Popup.open('cardsSort'), /* @@ -102,14 +132,22 @@ BlazeComponent.extendComponent({ */ 'click .js-filter-reset'(event) { event.stopPropagation(); - Sidebar.setView(); + if (Sidebar) { + Sidebar.setView(); + } else { + console.warn('Sidebar not available for setView'); + } Filter.reset(); }, 'click .js-sort-reset'() { Session.set('sortBy', ''); }, 'click .js-open-search-view'() { - Sidebar.setView('search'); + if (Sidebar) { + Sidebar.setView('search'); + } else { + console.warn('Sidebar not available for setView'); + } }, 'click .js-multiselection-activate'() { const currentCard = Utils.getCurrentCardId(); @@ -128,6 +166,7 @@ BlazeComponent.extendComponent({ }, ]; }, + }).register('boardHeaderBar'); Template.boardHeaderBar.helpers({ @@ -137,6 +176,23 @@ Template.boardHeaderBar.helpers({ isSortActive() { return Session.get('sortBy') ? true : false; }, + sortCardsIcon() { + const sortBy = Session.get('sortBy'); + if (!sortBy) { + return '🃏'; // Card icon when nothing is selected + } + + // Determine which sort option is active based on sortBy object + if (sortBy.dueAt) { + return '📅'; // Due date icon + } else if (sortBy.title) { + return '🔤'; // Alphabet icon + } else if (sortBy.createdAt) { + return sortBy.createdAt === 1 ? '⬆️' : '⬇️'; // Up/down arrow based on direction + } + + return '🃏'; // Default card icon + }, }); Template.boardChangeViewPopup.events({ @@ -203,6 +259,7 @@ const CreateBoard = BlazeComponent.extendComponent({ title: title, permission: 'private', type: 'template-container', + migrationVersion: 1, // Latest version - no migration needed }), ); @@ -237,6 +294,15 @@ const CreateBoard = BlazeComponent.extendComponent({ }, ); + // Assign to space if one was selected + const spaceId = Session.get('createBoardInWorkspace'); + if (spaceId) { + Meteor.call('assignBoardToWorkspace', this.boardId.get(), spaceId, (err) => { + if (err) console.error('Error assigning board to space:', err); + }); + Session.set('createBoardInWorkspace', null); // Clear after use + } + Utils.goBoardId(this.boardId.get()); } else { @@ -246,6 +312,7 @@ const CreateBoard = BlazeComponent.extendComponent({ Boards.insert({ title, permission: visibility, + migrationVersion: 1, // Latest version - no migration needed }), ); @@ -254,6 +321,15 @@ const CreateBoard = BlazeComponent.extendComponent({ boardId: this.boardId.get(), }); + // Assign to space if one was selected + const spaceId = Session.get('createBoardInWorkspace'); + if (spaceId) { + Meteor.call('assignBoardToWorkspace', this.boardId.get(), spaceId, (err) => { + if (err) console.error('Error assigning board to space:', err); + }); + Session.set('createBoardInWorkspace', null); // Clear after use + } + Utils.goBoardId(this.boardId.get()); } }, @@ -275,6 +351,13 @@ const CreateBoard = BlazeComponent.extendComponent({ }, }).register('createBoardPopup'); +(class CreateTemplateContainerPopup extends CreateBoard { + onRendered() { + // Always pre-check the template container checkbox for this popup + $('#add-template-container').addClass('is-checked'); + } +}).register('createTemplateContainerPopup'); + (class HeaderBarCreateBoard extends CreateBoard { onSubmit(event) { super.onSubmit(event); diff --git a/client/components/boards/boardsList.css b/client/components/boards/boardsList.css index 995b22445..dc7efdd66 100644 --- a/client/components/boards/boardsList.css +++ b/client/components/boards/boardsList.css @@ -8,6 +8,273 @@ padding: 1vh 0; } +/* Two-column layout for All Boards */ +.boards-layout { + display: grid; + grid-template-columns: 260px 1fr; + gap: 16px; +} + +.boards-left-menu { + border-right: 1px solid #e0e0e0; + padding-right: 12px; +} + +.boards-left-menu ul.menu { + list-style: none; + padding: 0; + margin: 0 0 12px 0; +} + +.boards-left-menu .menu-item { + margin: 4px 0; +} +.boards-left-menu .menu-item a { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 10px; + border-radius: 4px; + cursor: pointer; +} +.boards-left-menu .menu-item .menu-label { + flex: 1; +} +.boards-left-menu .menu-item .menu-count { + background: #ddd; + padding: 2px 8px; + border-radius: 12px; + font-size: 12px; + font-weight: bold; + margin-left: 8px; +} +.boards-left-menu .menu-item.active a, +.boards-left-menu .menu-item a:hover { + background: #f0f0f0; +} +.boards-left-menu .menu-item.active .menu-count { + background: #bbb; +} + +/* Drag-over state for menu items (for dropping boards on Remaining) */ +.boards-left-menu .menu-item a.drag-over { + background: #d0e8ff; + border: 2px dashed #2196F3; +} + +.workspaces-header { + display: flex; + align-items: center; + justify-content: space-between; + font-weight: bold; + margin-top: 12px; +} +.workspaces-header .js-add-space { + text-decoration: none; + font-weight: bold; + border: 1px solid #ccc; + padding: 2px 8px; + border-radius: 4px; +} + +.workspace-tree { + list-style: none; + padding-left: 10px; +} + +.workspace-node { + margin: 2px 0; + position: relative; +} + +.workspace-node-content { + display: flex; + align-items: center; + gap: 4px; + padding: 4px; + border-radius: 4px; + transition: background-color 0.2s; +} + +.workspace-node.dragging > .workspace-node-content { + opacity: 0.5; + background: #e0e0e0; +} + +.workspace-node.drag-over > .workspace-node-content { + background: #d0e8ff; + border: 2px dashed #2196F3; +} + +.workspace-drag-handle { + cursor: grab; + color: #999; + font-size: 14px; + padding: 0 4px; + user-select: none; +} + +.workspace-drag-handle:active { + cursor: grabbing; +} + +.workspace-node .js-select-space { + display: flex; + align-items: center; + gap: 6px; + padding: 4px 8px; + border-radius: 4px; + cursor: pointer; + flex: 1; + text-decoration: none; +} + +.workspace-node .workspace-icon { + font-size: 16px; + line-height: 1; +} + +.workspace-node .workspace-name { + flex: 1; +} + +.workspace-node .workspace-count { + background: #ddd; + padding: 2px 6px; + border-radius: 10px; + font-size: 11px; + font-weight: bold; + min-width: 20px; + text-align: center; +} + +.workspace-node .js-edit-space, +.workspace-node .js-add-subspace { + padding: 2px 6px; + border-radius: 3px; + cursor: pointer; + text-decoration: none; + font-size: 14px; + opacity: 0.6; + transition: opacity 0.2s; +} + +.workspace-node .js-edit-space:hover, +.workspace-node .js-add-subspace:hover { + opacity: 1; + background: #e0e0e0; +} + +.workspace-node.active > .workspace-node-content .js-select-space, +.workspace-node > .workspace-node-content:hover .js-select-space { + background: #f0f0f0; +} + +.workspace-node.active .workspace-count { + background: #bbb; +} + +.boards-right-grid { + min-height: 200px; +} + +.boards-path-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 12px 16px; + margin-bottom: 16px; + background: #f5f5f5; + border-radius: 6px; + font-size: 16px; + font-weight: 500; +} + +.boards-path-header .path-left { + display: flex; + align-items: center; + gap: 8px; + flex: 1; +} + +.boards-path-header .multiselection-hint { + background: #FFF3CD; + color: #856404; + padding: 4px 12px; + border-radius: 4px; + font-size: 13px; + font-weight: normal; + border: 1px solid #FFE69C; + animation: pulse 2s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.7; } +} + +.boards-path-header .path-right { + display: flex; + align-items: center; + gap: 8px; +} + +.boards-path-header .path-icon { + font-size: 18px; +} + +.boards-path-header .path-text { + color: #333; +} + +.boards-path-header .board-header-btn { + padding: 6px 12px; + background: #fff; + border: 1px solid #ddd; + border-radius: 4px; + cursor: pointer; + display: flex; + align-items: center; + gap: 6px; + font-size: 14px; + transition: all 0.2s; +} + +.boards-path-header .board-header-btn:hover { + background: #f0f0f0; + border-color: #bbb; +} + +.boards-path-header .board-header-btn.emphasis { + background: #2196F3; + color: #fff; + border-color: #2196F3; + font-weight: bold; + box-shadow: 0 2px 8px rgba(33, 150, 243, 0.5); + transform: scale(1.05); +} + +.boards-path-header .board-header-btn.emphasis:hover { + background: #1976D2; + box-shadow: 0 3px 12px rgba(33, 150, 243, 0.7); +} + +.boards-path-header .board-header-btn-close { + padding: 4px 10px; + background: #f44336; + color: #000; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 16px; + margin-left: 10px; /* Extra space between MultiSelection toggle and Remove Filter */ +} + +.boards-path-header .board-header-btn-close:hover { + background: #d32f2f; +} + .zoom-controls { display: flex; align-items: center; @@ -103,26 +370,38 @@ transform: rotate(4deg); display: block !important; } -.board-list li.starred .fa-star, -.board-list li.starred .fa-star-o { +.board-list li.starred .is-star-active, +.board-list li.starred .is-not-star-active { + opacity: 1; + color: #ffd700; +} +/* Show star icon on hover even for non-starred boards */ +.board-list li:hover .is-star-active, +.board-list li:hover .is-not-star-active { opacity: 1; } .board-list .board-list-item { overflow: hidden; - background-color: #999; + background-color: inherit; /* Inherit board color from parent li.js-board */ color: #f6f6f6; min-height: 100px; font-size: 16px; line-height: 22px; - border-radius: 3px; + border-radius: 0; /* No border-radius - parent .js-board has it */ display: block; font-weight: 700; - padding: 8px; - margin: 8px; + padding: 36px 8px 32px 8px; /* Top padding for drag handle, bottom for checkbox */ + margin: 0; /* No margin - moved to parent .js-board */ position: relative; text-decoration: none; word-wrap: break-word; } + +.board-list .board-list-item > .js-open-board { + text-decoration: none; + color: inherit; + display: block; +} .board-list .board-list-item.template-container { border: 4px solid #fff; } @@ -150,13 +429,20 @@ .board-list .js-add-board .label { font-weight: normal; line-height: 56px; + min-height: 100px; + display: flex; + align-items: center; + justify-content: center; + background-color: #999; /* Darker background for better text contrast */ + border-radius: 3px; + padding: 36px 8px 32px 8px; } -.board-list .js-add-board :hover { - background-color: #939393; +.board-list .js-add-board .label:hover { + background-color: #808080; /* Even darker on hover */ } -.board-list .fa-star, -.board-list .fa-star-o { - bottom: 0; +.board-list .is-star-active, +.board-list .is-not-star-active { + top: 0; font-size: 14px; height: 18px; line-height: 18px; @@ -164,7 +450,6 @@ padding: 9px 9px; position: absolute; right: 0; - top: 0; transition-duration: 0.15s; transition-property: color, font-size, background; } @@ -212,32 +497,121 @@ transition-duration: 0.15s; transition-property: color, font-size, background; } -.board-list li:hover a:hover .fa-star, +.board-list li:hover a:hover .is-star-active, .board-list li:hover a:hover .fa-clone, .board-list li:hover a:hover .fa-archive, -.board-list li:hover a:hover .fa-star-o { +.board-list li:hover a:hover .is-not-star-active { color: #fff; } -.board-list li:hover a .fa-star, +.board-list li:hover a .is-star-active, .board-list li:hover a .fa-clone, .board-list li:hover a .fa-archive, -.board-list li:hover a .fa-star-o { +.board-list li:hover a .is-not-star-active { color: #fff; opacity: 0.75; } -.board-list li:hover a .fa-star:hover, +.board-list li:hover a .is-star-active:hover, .board-list li:hover a .fa-clone:hover, .board-list li:hover a .fa-archive:hover, -.board-list li:hover a .fa-star-o:hover { +.board-list li:hover a .is-not-star-active:hover { font-size: 18px; opacity: 1; } -.board-list li:hover a .fa-star.is-star-active, -.board-list li:hover a .fa-clone.is-star-active, -.board-list li:hover a .fa-archive.is-star-active, -.board-list li:hover a .fa-star-o.is-star-active { +.board-list li:hover a .is-star-active, +.board-list li:hover a .fa-clone, +.board-list li:hover a .fa-archive, +.board-list li:hover a .is-not-star-active { opacity: 1; } + +/* Board drag handle - always visible and positioned at top */ +.board-list .board-handle { + position: absolute; + padding: 4px 6px; + top: 4px; + left: 50%; + transform: translateX(-50%); + font-size: 14px; + color: #fff; + background: rgba(0,0,0,0.4); + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + z-index: 10; + transition: background-color 0.2s ease; + cursor: grab; + opacity: 1; + user-select: none; +} + +.board-list .board-handle:active { + cursor: grabbing; +} + +.board-list .board-handle:hover { + background: rgba(255, 255, 0, 0.8) !important; + color: #000; +} + +/* Multiselection checkbox on board items */ +.board-list .board-list-item .multi-selection-checkbox { + position: absolute !important; + bottom: 4px !important; + left: 4px !important; + top: auto !important; + width: 24px; + height: 24px; + border: 3px solid #fff; + background: rgba(0,0,0,0.5); + border-radius: 4px; + cursor: pointer; + z-index: 11; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s; + box-shadow: 0 2px 4px rgba(0,0,0,0.3); + transform: none !important; + margin: 0 !important; +} + +.board-list .board-list-item .multi-selection-checkbox:hover { + background: rgba(0,0,0,0.7); + transform: scale(1.15) !important; + box-shadow: 0 3px 6px rgba(0,0,0,0.5); +} + +.board-list .board-list-item .multi-selection-checkbox.is-checked { + background: #2196F3; + border-color: #2196F3; + box-shadow: 0 2px 8px rgba(33, 150, 243, 0.6); + width: 24px !important; + height: 24px !important; + top: auto !important; + left: 4px !important; + transform: none !important; + border-radius: 4px !important; +} + +.board-list .board-list-item .multi-selection-checkbox.is-checked::after { + content: '✓'; + color: #fff; + font-size: 16px; + font-weight: bold; +} + +.board-list.is-multiselection-active .js-board.is-checked { + outline: 4px solid #2196F3; + outline-offset: -4px; + box-shadow: 0 4px 12px rgba(33, 150, 243, 0.4); +} + +/* Visual hint when multiselection is active */ +.board-list.is-multiselection-active .board-list-item { + border: 2px dashed rgba(33, 150, 243, 0.3); +} + .board-backgrounds-list .board-background-select { box-sizing: border-box; display: block; @@ -361,6 +735,18 @@ min-height: 100vh; /* Force content to be tall enough to scroll */ } +/* Hide archive and clone board buttons in mobile view */ +.board-list.mobile-view .js-archive-board, +.board-list.mobile-view .js-clone-board { + display: none !important; +} + +/* Change board drag handle to up-down arrow in mobile view */ +.board-list.mobile-view .board-handle.fa-arrows::before { + content: "↕️" !important; + font-family: inherit !important; +} + .board-list.mobile-view::after { content: ''; display: block; @@ -371,7 +757,8 @@ screen and (max-device-width: 800px), screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px), screen and (max-width: 800px) and (orientation: portrait), - screen and (max-width: 800px) and (orientation: landscape) { + screen and (max-width: 800px) and (orientation: landscape), + screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) { .board-list { height: 100%; overflow-y: auto; @@ -457,7 +844,8 @@ screen and (max-device-width: 800px), screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px), screen and (max-width: 800px) and (orientation: portrait), - screen and (max-width: 800px) and (orientation: landscape) { + screen and (max-width: 800px) and (orientation: landscape), + screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) { .wrapper { font-size: 2em !important; /* 2x bigger base font size for All Boards page */ } @@ -725,9 +1113,62 @@ #resetBtn { display: inline; } + +#resetBtn.filter-reset-btn { + background: #f44336; + color: #000; + border: none; + border-radius: 4px; + padding: 6px 12px; + cursor: pointer; + font-size: 14px; + display: inline-flex; + align-items: center; + gap: 6px; + transition: background 0.2s; +} + +#resetBtn.filter-reset-btn:hover { + background: #d32f2f; +} + +#resetBtn.filter-reset-btn .reset-icon { + font-size: 14px; +} + .js-board { display: block; + background-color: #999; /* Default gray background if no color class is applied */ + border-radius: 3px; /* Rounded corners for board items */ + overflow: hidden; /* Ensure children respect rounded corners */ + margin: 8px; /* Space between board items */ } + +/* Reset background for add-board button */ +.js-add-board { + background-color: transparent !important; + margin: 8px !important; /* Keep margin for add-board */ +} + +/* Apply board colors to li.js-board parent instead of just the link */ +.board-list .board-color-nephritis { background-color: #27ae60; } +.board-list .board-color-pomegranate { background-color: #c0392b; } +.board-list .board-color-belize { background-color: #2980b9; } +.board-list .board-color-wisteria { background-color: #8e44ad; } +.board-list .board-color-midnight { background-color: #2c3e50; } +.board-list .board-color-pumpkin { background-color: #e67e22; } +.board-list .board-color-moderatepink { background-color: #cd5a91; } +.board-list .board-color-strongcyan { background-color: #00aecc; } +.board-list .board-color-limegreen { background-color: #4bbf6b; } +.board-list .board-color-dark { background-color: #2c3e51; } +.board-list .board-color-relax { background-color: #27ae61; } +.board-list .board-color-corteza { background-color: #568ba2; } +.board-list .board-color-clearblue { background-color: #3498db; } +.board-list .board-color-natural { background-color: #596557; } +.board-list .board-color-modern { background-color: #2a80b8; } +.board-list .board-color-moderndark { background-color: #2a2a2a; } +.board-list .board-color-exodark { background-color: #222; } + .minicard-members { padding: 6px 0 6px 8px; width: 100%; @@ -757,7 +1198,8 @@ screen and (max-device-width: 800px), screen and (-webkit-min-device-pixel-ratio: 2) and (max-width: 800px), screen and (max-width: 800px) and (orientation: portrait), - screen and (max-width: 800px) and (orientation: landscape) { + screen and (max-width: 800px) and (orientation: landscape), + screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) { .wrapper { overflow: hidden; height: 100vh; @@ -824,5 +1266,17 @@ #content { overflow: hidden; } + + /* Hide archive and clone board buttons in mobile view */ + .board-list .js-archive-board, + .board-list .js-clone-board { + display: none !important; + } + + /* Change board drag handle to up-down arrow in mobile view */ + .board-list .board-handle.fa-arrows::before { + content: "↕️" !important; + font-family: inherit !important; + } } diff --git a/client/components/boards/boardsList.jade b/client/components/boards/boardsList.jade index f5fb4522e..5cf488c55 100644 --- a/client/components/boards/boardsList.jade +++ b/client/components/boards/boardsList.jade @@ -2,148 +2,160 @@ template(name="boardList") .wrapper .board-list-header - ul.AllBoardTeamsOrgs - li.AllBoardTeams - if userHasTeams - select.js-AllBoardTeams#jsAllBoardTeams("multiple") - option(value="-1") {{_ 'teams'}} : - each teamsDatas - option(value="{{teamId}}") {{_ teamDisplayName}} + .boards-layout + // Left menu + .boards-left-menu + ul.menu + li(class="menu-item {{#if isSelectedMenu 'starred'}}active{{/if}}") + a.js-select-menu(data-type="starred") + span.menu-label ⭐ {{_ 'allboards.starred'}} + span.menu-count {{menuItemCount 'starred'}} + li(class="menu-item {{#if isSelectedMenu 'templates'}}active{{/if}}") + a.js-select-menu(data-type="templates") + span.menu-label 📋 {{_ 'allboards.templates'}} + span.menu-count {{menuItemCount 'templates'}} + li(class="menu-item {{#if isSelectedMenu 'remaining'}}active{{/if}}") + a.js-select-menu(data-type="remaining") + span.menu-label 📂 {{_ 'allboards.remaining'}} + span.menu-count {{menuItemCount 'remaining'}} + .workspaces-header + span 🗂️ {{_ 'allboards.workspaces'}} + a.js-add-workspace(title="{{_ 'allboards.add-workspace'}}") + + // Workspaces tree + +workspaceTree(nodes=workspacesTree selectedWorkspaceId=selectedWorkspaceId) - li.AllBoardOrgs - if userHasOrgs - select.js-AllBoardOrgs#jsAllBoardOrgs("multiple") - option(value="-1") {{_ 'organizations'}} : - each orgsDatas - option(value="{{orgId}}") {{orgDisplayName}} + // Existing filter by orgs/teams (kept) + ul.AllBoardTeamsOrgs + li.AllBoardTeams + if userHasTeams + select.js-AllBoardTeams#jsAllBoardTeams("multiple") + option(value="-1") {{_ 'teams'}} : + each teamsDatas + option(value="{{teamId}}") {{_ teamDisplayName}} - //li.AllBoardTemplates - // if userHasTemplates - // select.js-AllBoardTemplates#jsAllBoardTemplates("multiple") - // option(value="-1") {{_ 'templates'}} : - // each templatesDatas - // option(value="{{templateId}}") {{_ templateDisplayName}} + li.AllBoardOrgs + if userHasOrgs + select.js-AllBoardOrgs#jsAllBoardOrgs("multiple") + option(value="-1") {{_ 'organizations'}} : + each orgsDatas + option(value="{{orgId}}") {{orgDisplayName}} - li.AllBoardBtns - div.AllBoardButtonsContainer - if userHasOrgsOrTeams - i.fa.fa-filter - input#filterBtn(type="button" value="{{_ 'filter'}}") - input#resetBtn(type="button" value="{{_ 'filter-clear'}}") + li.AllBoardBtns + div.AllBoardButtonsContainer + if userHasOrgsOrTeams + span 🔍 + input#filterBtn(type="button" value="{{_ 'filter'}}") + button#resetBtn.filter-reset-btn + span.reset-icon ❌ + span {{_ 'filter-clear'}} - ul.board-list.clearfix.js-boards(class="{{#if isMiniScreen}}mobile-view{{/if}}") - li.js-add-board - a.board-list-item.label(title="{{_ 'add-board'}}") - | {{_ 'add-board'}} - each boards - li(class="{{_id}}" class="{{#if isStarred}}starred{{/if}}" class=colorClass).js-board - if isInvited - .board-list-item - span.details - span.board-list-item-name= title - i.fa.js-star-board( - class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}" - title="{{_ 'star-board-title'}}") - p.board-list-item-desc {{_ 'just-invited'}} - button.js-accept-invite.primary {{_ 'accept'}} - button.js-decline-invite {{_ 'decline'}} - else - if $eq type "template-container" - a.js-open-board.template-container.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}") - span.details - span.board-list-item-name(title="{{_ 'template-container'}}") - +viewer - = title - i.fa.js-star-board( - class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}" - title="{{_ 'star-board-title'}}") - p.board-list-item-desc - +viewer - = description - if hasSpentTimeCards - i.fa.js-has-spenttime-cards( - class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}" - title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}") - if isTouchScreenOrShowDesktopDragHandles - i.fa.board-handle( - class="fa-arrows" - title="{{_ 'drag-board'}}") - else - if isSandstorm - i.fa.js-clone-board( - class="fa-clone" - title="{{_ 'duplicate-board'}}") - i.fa.js-archive-board( - class="fa-archive" - title="{{_ 'archive-board'}}") - else if isAdministrable - i.fa.js-clone-board( - class="fa-clone" - title="{{_ 'duplicate-board'}}") - i.fa.js-archive-board( - class="fa-archive" - title="{{_ 'archive-board'}}") - else if currentUser.isAdmin - i.fa.js-clone-board( - class="fa-clone" - title="{{_ 'duplicate-board'}}") - i.fa.js-archive-board( - class="fa-archive" - title="{{_ 'archive-board'}}") + // Right boards grid + .boards-right-grid + .boards-path-header + .path-left + span.path-icon {{currentMenuPath.icon}} + span.path-text {{currentMenuPath.text}} + if BoardMultiSelection.isActive + span.multiselection-hint 📌 {{_ 'multi-selection-active'}} + .path-right + if canModifyBoards + if hasBoardsSelected + button.js-archive-selected-boards.board-header-btn + span 📦 + span {{_ 'archive-board'}} + button.js-duplicate-selected-boards.board-header-btn + span 📋 + span {{_ 'duplicate-board'}} + a.board-header-btn.js-multiselection-activate( + title="{{#if BoardMultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}" + class="{{#if BoardMultiSelection.isActive}}emphasis{{/if}}") + | ☑️ + if BoardMultiSelection.isActive + a.board-header-btn-close.js-multiselection-reset(title="{{_ 'filter-clear'}}") + | ✖ + ul.board-list.clearfix.js-boards(class="{{#if isMiniScreen}}mobile-view{{/if}} {{#if BoardMultiSelection.isActive}}is-multiselection-active{{/if}}") + li.js-add-board + if isSelectedMenu 'templates' + a.board-list-item.label(title="{{_ 'add-template-container'}}") + | ➕ {{_ 'add-template-container'}} else - a.js-open-board.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}") - span.details - span.board-list-item-name(title="{{_ 'board-drag-drop-reorder-or-click-open'}}") - +viewer - = title - unless currentSetting.hideBoardMemberList - if allowsBoardMemberList - .minicard-members - each member in boardMembers _id - a.name - +userAvatar(userId=member noRemove=true) - unless currentSetting.hideCardCounterList - if allowsCardCounterList - .minicard-lists.flex.flex-wrap - each list in boardLists _id - .item - | {{ list }} - i.fa.js-star-board( - class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}" - title="{{_ 'star-board-title'}}") - p.board-list-item-desc - +viewer - = description - if hasSpentTimeCards - i.fa.js-has-spenttime-cards( - class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}" - title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}") - if isTouchScreenOrShowDesktopDragHandles - i.fa.board-handle( - class="fa-arrows" - title="{{_ 'drag-board'}}") - else - if isSandstorm - i.fa.js-clone-board( - class="fa-clone" - title="{{_ 'duplicate-board'}}") - i.fa.js-archive-board( - class="fa-archive" - title="{{_ 'archive-board'}}") - else if isAdministrable - i.fa.js-clone-board( - class="fa-clone" - title="{{_ 'duplicate-board'}}") - i.fa.js-archive-board( - class="fa-archive" - title="{{_ 'archive-board'}}") - else if currentUser.isAdmin - i.fa.js-clone-board( - class="fa-clone" - title="{{_ 'duplicate-board'}}") - i.fa.js-archive-board( - class="fa-archive" - title="{{_ 'archive-board'}}") + a.board-list-item.label(title="{{_ 'add-board'}}") + | ➕ {{_ 'add-board'}} + each boards + li.js-board(class="{{_id}} {{#if isStarred}}starred{{/if}} {{colorClass}} {{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}", draggable="true") + if isInvited + .board-list-item + if BoardMultiSelection.isActive + .materialCheckBox.multi-selection-checkbox.js-toggle-board-multi-selection( + class="{{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}") + span.details + span.board-list-item-name= title + span.js-star-board( + class="{{#if isStarred}}is-star-active{{else}}is-not-star-active{{/if}}" + title="{{_ 'star-board-title'}}") + | {{#if isStarred}}⭐{{else}}☆{{/if}} + p.board-list-item-desc {{_ 'just-invited'}} + button.js-accept-invite.primary {{_ 'accept'}} + button.js-decline-invite {{_ 'decline'}} + else + if $eq type "template-container" + .template-container.board-list-item + if BoardMultiSelection.isActive + .materialCheckBox.multi-selection-checkbox.js-toggle-board-multi-selection( + class="{{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}") + span.board-handle(title="{{_ 'drag-board'}}") ↕️ + a.js-open-board(href="{{pathFor 'board' id=_id slug=slug}}") + span.details + span.board-list-item-name(title="{{_ 'template-container'}}") + +viewer + = title + p.board-list-item-desc + +viewer + = description + if hasSpentTimeCards + span.js-has-spenttime-cards( + class="{{#if hasOvertimeCards}}has-overtime-card-active{{else}}no-overtime-card-active{{/if}}" + title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}") + | ⏱️ + span.js-star-board( + class="{{#if isStarred}}is-star-active{{else}}is-not-star-active{{/if}}" + title="{{_ 'star-board-title'}}") + | {{#if isStarred}}⭐{{else}}☆{{/if}} + else + .board-list-item + if BoardMultiSelection.isActive + .materialCheckBox.multi-selection-checkbox.js-toggle-board-multi-selection( + class="{{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}") + span.board-handle(title="{{_ 'drag-board'}}") ↕️ + a.js-open-board(href="{{pathFor 'board' id=_id slug=slug}}") + span.details + span.board-list-item-name(title="{{_ 'board-drag-drop-reorder-or-click-open'}}") + +viewer + = title + unless currentSetting.hideBoardMemberList + if allowsBoardMemberList + .minicard-members + each member in boardMembers _id + a.name + +userAvatar(userId=member noRemove=true) + unless currentSetting.hideCardCounterList + if allowsCardCounterList + .minicard-lists.flex.flex-wrap + each list in boardLists _id + .item + | {{ list }} + p.board-list-item-desc + +viewer + = description + if hasSpentTimeCards + span.js-has-spenttime-cards( + class="{{#if hasOvertimeCards}}has-overtime-card-active{{else}}no-overtime-card-active{{/if}}" + title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}") + | ⏱️ + a.js-star-board( + class="{{#if isStarred}}is-star-active{{else}}is-not-star-active{{/if}}" + title="{{_ 'star-board-title'}}") + | {{#if isStarred}}⭐{{else}}☆{{/if}} template(name="boardListHeaderBar") h1 {{_ title }} @@ -154,3 +166,25 @@ template(name="boardListHeaderBar") // a.board-header-btn(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") // i.fa.fa-clone // span {{_ 'templates'}} + +// Recursive template for workspaces tree +template(name="workspaceTree") + if nodes + ul.workspace-tree.js-workspace-tree + each nodes + li.workspace-node(class="{{#if $eq id selectedWorkspaceId}}active{{/if}}" data-workspace-id="{{id}}" draggable="true") + .workspace-node-content + span.workspace-drag-handle ↕️ + a.js-select-workspace(data-id="{{id}}") + span.workspace-icon + if icon + +viewer + = icon + else + | 📁 + span.workspace-name= name + a.js-edit-workspace(data-id="{{id}}" title="{{_ 'allboards.edit-workspace'}}") ✏️ + span.workspace-count {{workspaceCount id}} + a.js-add-subworkspace(data-id="{{id}}" title="{{_ 'allboards.add-subworkspace'}}") + + if children + +workspaceTree(nodes=children selectedWorkspaceId=selectedWorkspaceId) diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 1d655fd11..bb1d258d0 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -14,6 +14,9 @@ Template.boardList.helpers({ return Utils.isMiniScreen() && Session.get('currentBoard'); */ return true; }, + BoardMultiSelection() { + return BoardMultiSelection; + }, }) Template.boardListHeaderBar.events({ @@ -45,6 +48,9 @@ BlazeComponent.extendComponent({ onCreated() { Meteor.subscribe('setting'); Meteor.subscribe('tableVisibilityModeSettings'); + this.selectedMenu = new ReactiveVar('starred'); + this.selectedWorkspaceIdVar = new ReactiveVar(null); + this.workspacesTreeVar = new ReactiveVar([]); let currUser = ReactiveCache.getCurrentUser(); let userLanguage; if (currUser && currUser.profile) { @@ -53,9 +59,72 @@ BlazeComponent.extendComponent({ if (userLanguage) { TAPi18n.setLanguage(userLanguage); } + // Load workspaces tree reactively + this.autorun(() => { + const u = ReactiveCache.getCurrentUser(); + const tree = (u && u.profile && u.profile.boardWorkspacesTree) || []; + this.workspacesTreeVar.set(tree); + }); + }, + + reorderWorkspaces(draggedSpaceId, targetSpaceId) { + const tree = this.workspacesTreeVar.get(); + + // Helper to remove a space from tree + const removeSpace = (nodes, id) => { + for (let i = 0; i < nodes.length; i++) { + if (nodes[i].id === id) { + const removed = nodes.splice(i, 1)[0]; + return { tree: nodes, removed }; + } + if (nodes[i].children) { + const result = removeSpace(nodes[i].children, id); + if (result.removed) { + return { tree: nodes, removed: result.removed }; + } + } + } + return { tree: nodes, removed: null }; + }; + + // Helper to insert a space after target + const insertAfter = (nodes, targetId, spaceToInsert) => { + for (let i = 0; i < nodes.length; i++) { + if (nodes[i].id === targetId) { + nodes.splice(i + 1, 0, spaceToInsert); + return true; + } + if (nodes[i].children) { + if (insertAfter(nodes[i].children, targetId, spaceToInsert)) { + return true; + } + } + } + return false; + }; + + // Clone the tree + const newTree = EJSON.clone(tree); + + // Remove the dragged space + const { tree: treeAfterRemoval, removed } = removeSpace(newTree, draggedSpaceId); + + if (removed) { + // Insert after target + insertAfter(treeAfterRemoval, targetSpaceId, removed); + + // Save the new tree + Meteor.call('setWorkspacesTree', treeAfterRemoval, (err) => { + if (err) console.error(err); + }); + } }, onRendered() { + // jQuery sortable is disabled in favor of HTML5 drag-and-drop for space management + // The old sortable code has been removed to prevent conflicts + + /* OLD SORTABLE CODE - DISABLED const itemsSelector = '.js-board:not(.placeholder)'; const $boards = this.$('.js-boards'); @@ -73,27 +142,20 @@ BlazeComponent.extendComponent({ EscapeActions.executeUpTo('popup-close'); }, stop(evt, ui) { - // To attribute the new index number, we need to get the DOM element - // of the previous and the following card -- if any. const prevBoardDom = ui.item.prev('.js-board').get(0); - const nextBoardBom = ui.item.next('.js-board').get(0); - const sortIndex = Utils.calculateIndex(prevBoardDom, nextBoardBom, 1); + const nextBoardDom = ui.item.next('.js-board').get(0); + const sortIndex = Utils.calculateIndex(prevBoardDom, nextBoardDom, 1); const boardDomElement = ui.item.get(0); const board = Blaze.getData(boardDomElement); - // Normally the jquery-ui sortable library moves the dragged DOM element - // to its new position, which disrupts Blaze reactive updates mechanism - // (especially when we move the last card of a list, or when multiple - // users move some cards at the same time). To prevent these UX glitches - // we ask sortable to gracefully cancel the move, and to put back the - // DOM in its initial state. The card move is then handled reactively by - // Blaze with the below query. $boards.sortable('cancel'); - board.move(sortIndex.base); + const currentUser = ReactiveCache.getCurrentUser(); + if (currentUser && typeof currentUser.setBoardSortIndex === 'function') { + currentUser.setBoardSortIndex(board._id, sortIndex.base); + } }, }); - // Disable drag-dropping if the current user is not a board member or is comment only this.autorun(() => { if (Utils.isTouchScreenOrShowDesktopDragHandles()) { $boards.sortable({ @@ -101,6 +163,7 @@ BlazeComponent.extendComponent({ }); } }); + */ }, userHasTeams() { if (ReactiveCache.getCurrentUser()?.teams?.length > 0) @@ -132,6 +195,41 @@ BlazeComponent.extendComponent({ const ret = this.userHasOrgs() || this.userHasTeams(); return ret; }, + currentMenuPath() { + const sel = this.selectedMenu.get(); + const currentUser = ReactiveCache.getCurrentUser(); + + // Helper to find space by id in tree + const findSpaceById = (nodes, targetId, path = []) => { + for (const node of nodes) { + if (node.id === targetId) { + return [...path, node]; + } + if (node.children && node.children.length > 0) { + const result = findSpaceById(node.children, targetId, [...path, node]); + if (result) return result; + } + } + return null; + }; + + if (sel === 'starred') { + return { icon: '⭐', text: TAPi18n.__('allboards.starred') }; + } else if (sel === 'templates') { + return { icon: '📋', text: TAPi18n.__('allboards.templates') }; + } else if (sel === 'remaining') { + return { icon: '📂', text: TAPi18n.__('allboards.remaining') }; + } else { + // sel is a workspaceId, build path + const tree = this.workspacesTreeVar.get(); + const spacePath = findSpaceById(tree, sel); + if (spacePath && spacePath.length > 0) { + const pathText = spacePath.map(s => s.name).join(' / '); + return { icon: '🗂️', text: `${TAPi18n.__('allboards.workspaces')} / ${pathText}` }; + } + return { icon: '🗂️', text: TAPi18n.__('allboards.workspaces') }; + } + }, boards() { let query = { // { type: 'board' }, @@ -184,10 +282,33 @@ BlazeComponent.extendComponent({ }; } - const ret = ReactiveCache.getBoards(query, { - sort: { sort: 1 /* boards default sorting */ }, - }); - return ret; + const boards = ReactiveCache.getBoards(query, {}); + const currentUser = ReactiveCache.getCurrentUser(); + let list = boards; + // Apply left menu filtering + const sel = this.selectedMenu.get(); + const assignments = (currentUser && currentUser.profile && currentUser.profile.boardWorkspaceAssignments) || {}; + if (sel === 'starred') { + list = list.filter(b => currentUser && currentUser.hasStarred(b._id)); + } else if (sel === 'templates') { + list = list.filter(b => b.type === 'template-container'); + } else if (sel === 'remaining') { + // Show boards not in any workspace AND not templates + // Keep starred boards visible in Remaining too + list = list.filter(b => + !assignments[b._id] && + b.type !== 'template-container' + ); + } else { + // assume sel is a workspaceId + // Keep starred boards visible in their workspace too + list = list.filter(b => assignments[b._id] === sel); + } + + if (currentUser && typeof currentUser.sortBoardsForUser === 'function') { + return currentUser.sortBoardsForUser(list); + } + return list.slice().sort((a, b) => (a.title || '').localeCompare(b.title || '')); }, boardLists(boardId) { /* Bug Board icons random dance https://github.com/wekan/wekan/issues/4214 @@ -235,11 +356,65 @@ BlazeComponent.extendComponent({ events() { return [ { - 'click .js-add-board': Popup.open('createBoard'), - 'click .js-star-board'(evt) { - const boardId = this.currentData()._id; - ReactiveCache.getCurrentUser().toggleBoardStar(boardId); + 'click .js-select-menu'(evt) { + const type = evt.currentTarget.getAttribute('data-type'); + this.selectedWorkspaceIdVar.set(null); + this.selectedMenu.set(type); + }, + 'click .js-select-workspace'(evt) { + const id = evt.currentTarget.getAttribute('data-id'); + this.selectedWorkspaceIdVar.set(id); + this.selectedMenu.set(id); + }, + 'click .js-add-workspace'(evt) { evt.preventDefault(); + const name = prompt(TAPi18n.__('allboards.add-workspace-prompt') || 'New Space name'); + if (name && name.trim()) { + Meteor.call('createWorkspace', { parentId: null, name: name.trim() }, (err, res) => { + if (err) console.error(err); + }); + } + }, + 'click .js-add-board'(evt) { + // Store the currently selected workspace/menu for board creation + const selectedWorkspaceId = this.selectedWorkspaceIdVar.get(); + const selectedMenu = this.selectedMenu.get(); + + if (selectedWorkspaceId) { + Session.set('createBoardInWorkspace', selectedWorkspaceId); + } else { + Session.set('createBoardInWorkspace', null); + } + + // Open different popup based on context + if (selectedMenu === 'templates') { + Popup.open('createTemplateContainer')(evt); + } else { + Popup.open('createBoard')(evt); + } + }, + 'click .js-star-board'(evt) { + evt.preventDefault(); + evt.stopPropagation(); + const boardId = this.currentData()._id; + if (boardId) { + Meteor.call('toggleBoardStar', boardId); + } + }, + // HTML5 DnD from boards to spaces + 'dragstart .js-board'(evt) { + const boardId = this.currentData()._id; + + // Support multi-drag + if (BoardMultiSelection.isActive() && BoardMultiSelection.isSelected(boardId)) { + const selectedIds = BoardMultiSelection.getSelectedBoardIds(); + try { + evt.originalEvent.dataTransfer.setData('text/plain', JSON.stringify(selectedIds)); + evt.originalEvent.dataTransfer.setData('application/x-board-multi', 'true'); + } catch (e) {} + } else { + try { evt.originalEvent.dataTransfer.setData('text/plain', boardId); } catch (e) {} + } }, 'click .js-clone-board'(evt) { if (confirm(TAPi18n.__('duplicate-board-confirm'))) { @@ -290,6 +465,58 @@ BlazeComponent.extendComponent({ } }); }, + 'click .js-multiselection-activate'(evt) { + evt.preventDefault(); + if (BoardMultiSelection.isActive()) { + BoardMultiSelection.disable(); + } else { + BoardMultiSelection.activate(); + } + }, + 'click .js-multiselection-reset'(evt) { + evt.preventDefault(); + BoardMultiSelection.disable(); + }, + 'click .js-toggle-board-multi-selection'(evt) { + evt.preventDefault(); + evt.stopPropagation(); + const boardId = this.currentData()._id; + BoardMultiSelection.toogle(boardId); + }, + 'click .js-archive-selected-boards'(evt) { + evt.preventDefault(); + const selectedBoards = BoardMultiSelection.getSelectedBoardIds(); + if (selectedBoards.length > 0 && confirm(TAPi18n.__('archive-board-confirm'))) { + selectedBoards.forEach(boardId => { + Meteor.call('archiveBoard', boardId); + }); + BoardMultiSelection.reset(); + } + }, + 'click .js-duplicate-selected-boards'(evt) { + evt.preventDefault(); + const selectedBoards = BoardMultiSelection.getSelectedBoardIds(); + if (selectedBoards.length > 0 && confirm(TAPi18n.__('duplicate-board-confirm'))) { + selectedBoards.forEach(boardId => { + const board = ReactiveCache.getBoard(boardId); + if (board) { + Meteor.call( + 'copyBoard', + boardId, + { + sort: ReactiveCache.getBoards({ archived: false }).length, + type: 'board', + title: board.title, + }, + (err, res) => { + if (err) console.error(err); + } + ); + } + }); + BoardMultiSelection.reset(); + } + }, 'click #resetBtn'(event) { let allBoards = document.getElementsByClassName("js-board"); let currBoard; @@ -356,7 +583,260 @@ BlazeComponent.extendComponent({ } } }, + 'click .js-edit-workspace'(evt) { + evt.preventDefault(); + evt.stopPropagation(); + const workspaceId = evt.currentTarget.getAttribute('data-id'); + + // Find the space in the tree + const findSpace = (nodes, id) => { + for (const node of nodes) { + if (node.id === id) return node; + if (node.children) { + const found = findSpace(node.children, id); + if (found) return found; + } + } + return null; + }; + + const tree = this.workspacesTreeVar.get(); + const space = findSpace(tree, workspaceId); + + if (space) { + const newName = prompt(TAPi18n.__('allboards.edit-workspace-name') || 'Space name:', space.name); + const newIcon = prompt(TAPi18n.__('allboards.edit-workspace-icon') || 'Space icon (markdown):', space.icon || '📁'); + + if (newName !== null && newName.trim()) { + // Update space in tree + const updateSpaceInTree = (nodes, id, updates) => { + return nodes.map(node => { + if (node.id === id) { + return { ...node, ...updates }; + } + if (node.children) { + return { ...node, children: updateSpaceInTree(node.children, id, updates) }; + } + return node; + }); + }; + + const updatedTree = updateSpaceInTree(tree, workspaceId, { + name: newName.trim(), + icon: newIcon || '📁' + }); + + Meteor.call('setWorkspacesTree', updatedTree, (err) => { + if (err) console.error(err); + }); + } + } + }, + 'click .js-add-subworkspace'(evt) { + evt.preventDefault(); + evt.stopPropagation(); + const parentId = evt.currentTarget.getAttribute('data-id'); + const name = prompt(TAPi18n.__('allboards.add-subworkspace-prompt') || 'Subspace name:'); + + if (name && name.trim()) { + Meteor.call('createWorkspace', { parentId, name: name.trim() }, (err) => { + if (err) console.error(err); + }); + } + }, + 'dragstart .workspace-node'(evt) { + const workspaceId = evt.currentTarget.getAttribute('data-workspace-id'); + evt.originalEvent.dataTransfer.effectAllowed = 'move'; + evt.originalEvent.dataTransfer.setData('application/x-workspace-id', workspaceId); + + // Create a better drag image + const dragImage = evt.currentTarget.cloneNode(true); + dragImage.style.position = 'absolute'; + dragImage.style.top = '-9999px'; + dragImage.style.opacity = '0.8'; + document.body.appendChild(dragImage); + evt.originalEvent.dataTransfer.setDragImage(dragImage, 0, 0); + setTimeout(() => document.body.removeChild(dragImage), 0); + + evt.currentTarget.classList.add('dragging'); + }, + 'dragend .workspace-node'(evt) { + evt.currentTarget.classList.remove('dragging'); + document.querySelectorAll('.workspace-node').forEach(el => { + el.classList.remove('drag-over'); + }); + }, + 'dragover .workspace-node'(evt) { + evt.preventDefault(); + evt.stopPropagation(); + + const draggingEl = document.querySelector('.workspace-node.dragging'); + const targetEl = evt.currentTarget; + + // Allow dropping boards on any space + // Or allow dropping spaces on other spaces (but not on itself or descendants) + if (!draggingEl || (targetEl !== draggingEl && !draggingEl.contains(targetEl))) { + evt.originalEvent.dataTransfer.dropEffect = 'move'; + targetEl.classList.add('drag-over'); + } + }, + 'dragleave .workspace-node'(evt) { + evt.currentTarget.classList.remove('drag-over'); + }, + 'drop .workspace-node'(evt) { + evt.preventDefault(); + evt.stopPropagation(); + + const targetEl = evt.currentTarget; + targetEl.classList.remove('drag-over'); + + // Check what's being dropped - board or workspace + const draggedWorkspaceId = evt.originalEvent.dataTransfer.getData('application/x-workspace-id'); + const isMultiBoard = evt.originalEvent.dataTransfer.getData('application/x-board-multi'); + const boardData = evt.originalEvent.dataTransfer.getData('text/plain'); + + if (draggedWorkspaceId && !boardData) { + // This is a workspace reorder operation + const targetWorkspaceId = targetEl.getAttribute('data-workspace-id'); + + if (draggedWorkspaceId !== targetWorkspaceId) { + this.reorderWorkspaces(draggedWorkspaceId, targetWorkspaceId); + } + } else if (boardData) { + // This is a board assignment operation + // Get the workspace ID directly from the dropped workspace-node's data-workspace-id attribute + const workspaceId = targetEl.getAttribute('data-workspace-id'); + + if (workspaceId) { + if (isMultiBoard) { + // Multi-board drag + try { + const boardIds = JSON.parse(boardData); + boardIds.forEach(boardId => { + Meteor.call('assignBoardToWorkspace', boardId, workspaceId); + }); + } catch (e) { + // Error parsing multi-board data + } + } else { + // Single board drag + Meteor.call('assignBoardToWorkspace', boardData, workspaceId); + } + } + } + }, + 'dragover .js-select-menu'(evt) { + evt.preventDefault(); + evt.stopPropagation(); + + const menuType = evt.currentTarget.getAttribute('data-type'); + // Only allow drop on "remaining" menu to unassign boards from spaces + if (menuType === 'remaining') { + evt.originalEvent.dataTransfer.dropEffect = 'move'; + evt.currentTarget.classList.add('drag-over'); + } + }, + 'dragleave .js-select-menu'(evt) { + evt.currentTarget.classList.remove('drag-over'); + }, + 'drop .js-select-menu'(evt) { + evt.preventDefault(); + evt.stopPropagation(); + + const menuType = evt.currentTarget.getAttribute('data-type'); + evt.currentTarget.classList.remove('drag-over'); + + // Only handle drops on "remaining" menu + if (menuType !== 'remaining') return; + + const isMultiBoard = evt.originalEvent.dataTransfer.getData('application/x-board-multi'); + const boardData = evt.originalEvent.dataTransfer.getData('text/plain'); + + if (boardData) { + if (isMultiBoard) { + // Multi-board drag - unassign all from workspaces + try { + const boardIds = JSON.parse(boardData); + boardIds.forEach(boardId => { + Meteor.call('unassignBoardFromWorkspace', boardId); + }); + } catch (e) { + // Error parsing multi-board data + } + } else { + // Single board drag - unassign from workspace + Meteor.call('unassignBoardFromWorkspace', boardData); + } + } + }, }, ]; }, + // Helpers for templates + workspacesTree() { + return this.workspacesTreeVar.get(); + }, + selectedWorkspaceId() { + return this.selectedWorkspaceIdVar.get(); + }, + isSelectedMenu(type) { + return this.selectedMenu.get() === type; + }, + isSpaceSelected(id) { + return this.selectedWorkspaceIdVar.get() === id; + }, + menuItemCount(type) { + const currentUser = ReactiveCache.getCurrentUser(); + const assignments = (currentUser && currentUser.profile && currentUser.profile.boardWorkspaceAssignments) || {}; + + // Get all boards for counting + let query = { + $and: [ + { archived: false }, + { type: { $in: ['board', 'template-container'] } }, + { $or: [{ 'members.userId': Meteor.userId() }] }, + { title: { $not: { $regex: /^\^.*\^$/ } } } + ] + }; + const allBoards = ReactiveCache.getBoards(query, {}); + + if (type === 'starred') { + return allBoards.filter(b => currentUser && currentUser.hasStarred(b._id)).length; + } else if (type === 'templates') { + return allBoards.filter(b => b.type === 'template-container').length; + } else if (type === 'remaining') { + // Count boards not in any workspace AND not templates + // Include starred boards (they appear in both Starred and Remaining) + return allBoards.filter(b => + !assignments[b._id] && + b.type !== 'template-container' + ).length; + } + return 0; + }, + workspaceCount(workspaceId) { + const currentUser = ReactiveCache.getCurrentUser(); + const assignments = (currentUser && currentUser.profile && currentUser.profile.boardWorkspaceAssignments) || {}; + + // Get all boards for counting + let query = { + $and: [ + { archived: false }, + { type: { $in: ['board', 'template-container'] } }, + { $or: [{ 'members.userId': Meteor.userId() }] }, + { title: { $not: { $regex: /^\^.*\^$/ } } } + ] + }; + const allBoards = ReactiveCache.getBoards(query, {}); + + // Count boards directly assigned to this space (not including children) + return allBoards.filter(b => assignments[b._id] === workspaceId).length; + }, + canModifyBoards() { + const currentUser = ReactiveCache.getCurrentUser(); + return currentUser && !currentUser.isCommentOnly(); + }, + hasBoardsSelected() { + return BoardMultiSelection.count() > 0; + }, }).register('boardList'); diff --git a/client/components/boards/originalPositionsView.css b/client/components/boards/originalPositionsView.css new file mode 100644 index 000000000..ec3abd4c5 --- /dev/null +++ b/client/components/boards/originalPositionsView.css @@ -0,0 +1,263 @@ +/* Original Positions View Styles */ +.original-positions-view { + margin: 10px 0; + padding: 15px; + background-color: #f8f9fa; + border: 1px solid #e9ecef; + border-radius: 6px; +} + +.original-positions-header { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 15px; +} + +.original-positions-header .btn { + display: flex; + align-items: center; + gap: 5px; +} + +.original-positions-content { + background-color: white; + border: 1px solid #dee2e6; + border-radius: 4px; + padding: 15px; +} + +.original-positions-loading { + text-align: center; + padding: 20px; + color: #6c757d; + font-style: italic; +} + +.original-positions-loading i { + margin-right: 8px; +} + +.original-positions-filters { + margin-bottom: 20px; + padding-bottom: 15px; + border-bottom: 1px solid #dee2e6; +} + +.original-positions-filters .btn-group { + display: flex; + flex-wrap: wrap; + gap: 5px; +} + +.original-positions-filters .btn { + display: flex; + align-items: center; + gap: 5px; + white-space: nowrap; +} + +.original-positions-list { + max-height: 400px; + overflow-y: auto; +} + +.original-position-item { + background-color: #f8f9fa; + border: 1px solid #e9ecef; + border-radius: 4px; + margin-bottom: 10px; + padding: 12px; + transition: all 0.2s ease; +} + +.original-position-item:hover { + background-color: #e9ecef; + border-color: #ced4da; +} + +.original-position-item:last-child { + margin-bottom: 0; +} + +.original-position-item-header { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 8px; + font-weight: 600; + color: #495057; +} + +.original-position-item-header i { + color: #6c757d; + width: 16px; + text-align: center; +} + +.entity-type { + background-color: #007bff; + color: white; + padding: 2px 6px; + border-radius: 3px; + font-size: 11px; + font-weight: 500; + text-transform: uppercase; +} + +.entity-name { + color: #212529; + font-weight: 600; +} + +.entity-id { + color: #6c757d; + font-size: 11px; + font-family: monospace; +} + +.original-position-item-details { + margin-left: 24px; +} + +.original-position-description { + color: #495057; + margin-bottom: 6px; + font-size: 13px; +} + +.original-title { + color: #6c757d; + font-size: 12px; + margin-bottom: 6px; + padding: 4px 6px; + background-color: #e9ecef; + border-radius: 3px; +} + +.original-title strong { + color: #495057; +} + +.original-position-date { + color: #6c757d; + font-size: 11px; +} + +.no-original-positions { + text-align: center; + padding: 40px 20px; + color: #6c757d; + font-style: italic; +} + +.no-original-positions i { + font-size: 24px; + margin-bottom: 10px; + display: block; + color: #adb5bd; +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .original-positions-view { + margin: 5px 0; + padding: 10px; + } + + .original-positions-header { + flex-direction: column; + align-items: stretch; + gap: 8px; + } + + .original-positions-header .btn { + justify-content: center; + } + + .original-positions-filters .btn-group { + justify-content: center; + } + + .original-position-item-header { + flex-wrap: wrap; + gap: 6px; + } + + .entity-name { + flex: 1; + min-width: 0; + word-break: break-word; + } + + .original-position-item-details { + margin-left: 0; + margin-top: 8px; + } +} + +/* Dark theme support */ +@media (prefers-color-scheme: dark) { + .original-positions-view { + background-color: #2d3748; + border-color: #4a5568; + color: #e2e8f0; + } + + .original-positions-content { + background-color: #1a202c; + border-color: #4a5568; + } + + .original-position-item { + background-color: #2d3748; + border-color: #4a5568; + color: #e2e8f0; + } + + .original-position-item:hover { + background-color: #4a5568; + border-color: #718096; + } + + .original-position-item-header { + color: #e2e8f0; + } + + .original-position-item-header i { + color: #a0aec0; + } + + .entity-name { + color: #e2e8f0; + } + + .entity-id { + color: #a0aec0; + } + + .original-position-description { + color: #e2e8f0; + } + + .original-title { + background-color: #4a5568; + color: #a0aec0; + } + + .original-title strong { + color: #e2e8f0; + } + + .original-position-date { + color: #a0aec0; + } + + .no-original-positions { + color: #a0aec0; + } + + .no-original-positions i { + color: #718096; + } +} diff --git a/client/components/boards/originalPositionsView.html b/client/components/boards/originalPositionsView.html new file mode 100644 index 000000000..6a58beeb0 --- /dev/null +++ b/client/components/boards/originalPositionsView.html @@ -0,0 +1,82 @@ + diff --git a/client/components/boards/originalPositionsView.js b/client/components/boards/originalPositionsView.js new file mode 100644 index 000000000..1e73796be --- /dev/null +++ b/client/components/boards/originalPositionsView.js @@ -0,0 +1,148 @@ +import { BlazeComponent } from 'meteor/peerlibrary:blaze-components'; +import { ReactiveVar } from 'meteor/reactive-var'; +import { Meteor } from 'meteor/meteor'; +import { Template } from 'meteor/templating'; +import './originalPositionsView.html'; + +/** + * Component to display original positions for all entities on a board + */ +class OriginalPositionsViewComponent extends BlazeComponent { + onCreated() { + super.onCreated(); + this.showOriginalPositions = new ReactiveVar(false); + this.boardHistory = new ReactiveVar([]); + this.isLoading = new ReactiveVar(false); + this.filterType = new ReactiveVar('all'); // 'all', 'swimlane', 'list', 'card' + } + + onRendered() { + super.onRendered(); + this.loadBoardHistory(); + } + + loadBoardHistory() { + const boardId = Session.get('currentBoard'); + if (!boardId) return; + + this.isLoading.set(true); + + Meteor.call('positionHistory.getBoardHistory', boardId, (error, result) => { + this.isLoading.set(false); + if (error) { + console.error('Error loading board history:', error); + this.boardHistory.set([]); + } else { + this.boardHistory.set(result); + } + }); + } + + toggleOriginalPositions() { + this.showOriginalPositions.set(!this.showOriginalPositions.get()); + } + + isShowingOriginalPositions() { + return this.showOriginalPositions.get(); + } + + isLoading() { + return this.isLoading.get(); + } + + getBoardHistory() { + return this.boardHistory.get(); + } + + getFilteredHistory() { + const history = this.getBoardHistory(); + const filterType = this.filterType.get(); + + if (filterType === 'all') { + return history; + } + + return history.filter(item => item.entityType === filterType); + } + + getSwimlanesHistory() { + return this.getBoardHistory().filter(item => item.entityType === 'swimlane'); + } + + getListsHistory() { + return this.getBoardHistory().filter(item => item.entityType === 'list'); + } + + getCardsHistory() { + return this.getBoardHistory().filter(item => item.entityType === 'card'); + } + + setFilterType(type) { + this.filterType.set(type); + } + + getFilterType() { + return this.filterType.get(); + } + + getEntityDisplayName(entity) { + const position = entity.originalPosition || {}; + return position.title || `Entity ${entity.entityId}`; + } + + getEntityOriginalPositionDescription(entity) { + const position = entity.originalPosition || {}; + let description = `Position: ${position.sort || 0}`; + + if (entity.entityType === 'list' && entity.originalSwimlaneId) { + description += ` in swimlane ${entity.originalSwimlaneId}`; + } else if (entity.entityType === 'card') { + if (entity.originalSwimlaneId) { + description += ` in swimlane ${entity.originalSwimlaneId}`; + } + if (entity.originalListId) { + description += ` in list ${entity.originalListId}`; + } + } + + return description; + } + + getEntityTypeIcon(entityType) { + switch (entityType) { + case 'swimlane': + return 'fa-bars'; + case 'list': + return 'fa-columns'; + case 'card': + return 'fa-sticky-note'; + default: + return 'fa-question'; + } + } + + getEntityTypeLabel(entityType) { + switch (entityType) { + case 'swimlane': + return 'Swimlane'; + case 'list': + return 'List'; + case 'card': + return 'Card'; + default: + return 'Unknown'; + } + } + + formatDate(date) { + return new Date(date).toLocaleString(); + } + + refreshHistory() { + this.loadBoardHistory(); + } +} + +OriginalPositionsViewComponent.register('originalPositionsView'); + +export default OriginalPositionsViewComponent; diff --git a/client/components/cards/attachments.css b/client/components/cards/attachments.css index 64a0c8735..becb29160 100644 --- a/client/components/cards/attachments.css +++ b/client/components/cards/attachments.css @@ -336,3 +336,36 @@ margin-top: 10px; } } + +/* Attachment migration styles */ +.attachment-item.migrating { + position: relative; + opacity: 0.7; +} + +.attachment-migration-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(255, 255, 255, 0.9); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + z-index: 10; + border-radius: 4px; +} + +.migration-spinner { + font-size: 24px; + color: #007cba; + margin-bottom: 8px; +} + +.migration-text { + font-size: 12px; + color: #666; + text-align: center; +} diff --git a/client/components/cards/attachments.jade b/client/components/cards/attachments.jade index 5e1d41da1..34a9b2496 100644 --- a/client/components/cards/attachments.jade +++ b/client/components/cards/attachments.jade @@ -34,10 +34,10 @@ template(name="attachmentViewer") #viewer-overlay.hidden #viewer-top-bar span#attachment-name - a#viewer-close.fa.fa-times-thin + a#viewer-close ❌ #viewer-container - i.fa.fa-chevron-left.attachment-arrow#prev-attachment + | ◀️ #viewer-content img#image-viewer.hidden video#video-viewer.hidden(controls="true") @@ -45,7 +45,7 @@ template(name="attachmentViewer") object#pdf-viewer.hidden(type="application/pdf") span.pdf-preview-error {{_ 'preview-pdf-not-supported' }} object#txt-viewer.hidden(type="text/plain") - i.fa.fa-chevron-right.attachment-arrow#next-attachment + | ▶️ template(name="attachmentGallery") @@ -53,11 +53,11 @@ template(name="attachmentGallery") if canModifyCard a.attachment-item.add-attachment.js-add-attachment - i.fa.fa-plus.icon + | ➕ each attachments - .attachment-item + .attachment-item(class="{{#if isAttachmentMigrating _id}}migrating{{/if}}") .attachment-thumbnail-container.open-preview(data-attachment-id="{{_id}}" data-card-id="{{ meta.cardId }}") if link if(isImage) @@ -86,25 +86,32 @@ template(name="attachmentGallery") = name span.file-size ({{fileSize size}}) .attachment-actions - a.js-download(href="{{link}}?download=true", download="{{name}}") - i.fa.fa-download.icon(title="{{_ 'download'}}") + a.js-download(href="{{link}}?download=true", download="{{name}}", title="{{_ 'download'}}") + | ⬇️ if currentUser.isBoardMember unless currentUser.isCommentOnly unless currentUser.isWorker - a.js-rename - i.fa.fa-pencil-square-o.icon(title="{{_ 'rename'}}") - a.js-confirm-delete - i.fa.fa-trash.icon(title="{{_ 'delete'}}") - a.fa.fa-navicon.icon.js-open-attachment-menu(data-attachment-link="{{link}}" title="{{_ 'attachmentActionsPopup-title'}}") + a.js-rename(title="{{_ 'rename'}}") + | ✏️ + a.js-confirm-delete(title="{{_ 'delete'}}") + | 🗑️ + a.js-open-attachment-menu(data-attachment-link="{{link}}", title="{{_ 'attachmentActionsPopup-title'}}") + | ☰ + // Migration spinner overlay + if isAttachmentMigrating _id + .attachment-migration-overlay + .migration-spinner + | ⚙️ + .migration-text {{_ 'migrating-attachment'}} template(name="attachmentActionsPopup") ul.pop-over-list li if isImage a(class="{{#if isCover}}js-remove-cover{{else}}js-add-cover{{/if}}") - i.fa.fa-book - i.fa.fa-picture-o + | 📖 + | 🖼️ if isCover | {{_ 'remove-cover'}} else @@ -112,7 +119,7 @@ template(name="attachmentActionsPopup") if currentUser.isBoardAdmin if isImage a(class="{{#if isBackgroundImage}}js-remove-background-image{{else}}js-add-background-image{{/if}}") - i.fa.fa-picture-o + | 🖼️ if isBackgroundImage | {{_ 'remove-background-image'}} else @@ -120,19 +127,19 @@ template(name="attachmentActionsPopup") if $neq versions.original.storage "fs" a.js-move-storage-fs - i.fa.fa-arrow-right + | ▶️ | {{_ 'attachment-move-storage-fs'}} if $neq versions.original.storage "gridfs" if versions.original.storage a.js-move-storage-gridfs - i.fa.fa-arrow-right + | ▶️ | {{_ 'attachment-move-storage-gridfs'}} if $neq versions.original.storage "s3" if versions.original.storage a.js-move-storage-s3 - i.fa.fa-arrow-right + | ▶️ | {{_ 'attachment-move-storage-s3'}} template(name="attachmentRenamePopup") diff --git a/client/components/cards/attachments.js b/client/components/cards/attachments.js index 51304cf92..a883877e1 100644 --- a/client/components/cards/attachments.js +++ b/client/components/cards/attachments.js @@ -3,6 +3,7 @@ import { ObjectID } from 'bson'; import DOMPurify from 'dompurify'; import { sanitizeHTML, sanitizeText } from '/imports/lib/secureDOMPurify'; import uploadProgressManager from '../../lib/uploadProgressManager'; +import { attachmentMigrationManager } from '/client/lib/attachmentMigrationManager'; const filesize = require('filesize'); const prettyMilliseconds = require('pretty-ms'); @@ -342,7 +343,7 @@ export function handleFileUpload(card, files) { } // Check if user can modify the card - if (!card.canModifyCard()) { + if (!Utils.canModifyCard()) { if (process.env.DEBUG === 'true') { console.warn('User does not have permission to modify this card'); } @@ -576,3 +577,20 @@ BlazeComponent.extendComponent({ ] } }).register('attachmentRenamePopup'); + +// Template helpers for attachment migration status +Template.registerHelper('attachmentMigrationStatus', function(attachmentId) { + return attachmentMigrationManager.getAttachmentMigrationStatus(attachmentId); +}); + +Template.registerHelper('isAttachmentMigrating', function(attachmentId) { + return attachmentMigrationManager.isAttachmentBeingMigrated(attachmentId); +}); + +Template.registerHelper('attachmentMigrationProgress', function() { + return attachmentMigrationManager.attachmentMigrationProgress.get(); +}); + +Template.registerHelper('attachmentMigrationStatusText', function() { + return attachmentMigrationManager.attachmentMigrationStatus.get(); +}); diff --git a/client/components/cards/cardCustomFields.jade b/client/components/cards/cardCustomFields.jade index cefeaac88..35afa772b 100644 --- a/client/components/cards/cardCustomFields.jade +++ b/client/components/cards/cardCustomFields.jade @@ -6,10 +6,10 @@ template(name="cardCustomFieldsPopup") span.full-name = name if hasCustomField - i.fa.fa-check + | ✅ hr a.quiet-button.full.js-settings - i.fa.fa-cog + | ⚙️ span {{_ 'settings'}} template(name="cardCustomField") @@ -22,7 +22,7 @@ template(name="cardCustomField-text") = value .edit-controls.clearfix button.primary(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form else a.js-open-inlined-form if value @@ -41,7 +41,7 @@ template(name="cardCustomField-number") input(type="number" value=data.value) .edit-controls.clearfix button.primary(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form else a.js-open-inlined-form if value @@ -66,7 +66,7 @@ template(name="cardCustomField-currency") input(type="text" value=data.value autofocus) .edit-controls.clearfix button.primary(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form else a.js-open-inlined-form if value @@ -113,7 +113,7 @@ template(name="cardCustomField-dropdown") = name .edit-controls.clearfix button.primary(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form else a.js-open-inlined-form if value @@ -134,7 +134,7 @@ template(name="cardCustomField-stringtemplate") 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 + a.js-close-inlined-form else a.js-open-inlined-form if value diff --git a/client/components/cards/cardCustomFields.js b/client/components/cards/cardCustomFields.js index 23647ce53..82c025503 100644 --- a/client/components/cards/cardCustomFields.js +++ b/client/components/cards/cardCustomFields.js @@ -1,6 +1,27 @@ -import moment from 'moment/min/moment-with-locales'; import { TAPi18n } from '/imports/i18n'; import { DatePicker } from '/client/lib/datepicker'; +import { ReactiveCache } from '/imports/reactiveCache'; +import { + formatDateTime, + formatDate, + formatDateByUserPreference, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; import Cards from '/models/cards'; import { CustomFieldStringTemplate } from '/client/lib/customFields' @@ -134,31 +155,33 @@ CardCustomField.register('cardCustomField'); super.onCreated(); const self = this; self.date = ReactiveVar(); - self.now = ReactiveVar(moment()); + self.now = ReactiveVar(now()); window.setInterval(() => { - self.now.set(moment()); + self.now.set(now()); }, 60000); self.autorun(() => { - self.date.set(moment(self.data().value)); + self.date.set(new Date(self.data().value)); }); } showWeek() { - return this.date.get().week().toString(); + return getISOWeek(this.date.get()).toString(); } showWeekOfYear() { - return ReactiveCache.getCurrentUser().isShowWeekOfYear(); + const user = ReactiveCache.getCurrentUser(); + if (!user) { + // For non-logged-in users, week of year is not shown + return false; + } + return user.isShowWeekOfYear(); } showDate() { - // this will start working once mquandalle:moment - // is updated to at least moment.js 2.10.5 - // until then, the date is displayed in the "L" format - return this.date.get().calendar(null, { - sameElse: 'llll', - }); + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + return formatDateByUserPreference(this.date.get(), dateFormat, true); } showISODate() { @@ -167,8 +190,8 @@ CardCustomField.register('cardCustomField'); classes() { if ( - this.date.get().isBefore(this.now.get(), 'minute') && - this.now.get().isBefore(this.data().value) + isBefore(this.date.get(), this.now.get(), 'minute') && + isBefore(this.now.get(), this.data().value, 'minute') ) { return 'current'; } @@ -176,7 +199,7 @@ CardCustomField.register('cardCustomField'); } showTitle() { - return `${TAPi18n.__('card-start-on')} ${this.date.get().format('LLLL')}`; + return `${TAPi18n.__('card-start-on')} ${this.date.get().toLocaleString()}`; } events() { @@ -195,7 +218,7 @@ CardCustomField.register('cardCustomField'); const self = this; self.card = Utils.getCurrentCard(); self.customFieldId = this.data()._id; - this.data().value && this.date.set(moment(this.data().value)); + this.data().value && this.date.set(new Date(this.data().value)); } _storeDate(date) { diff --git a/client/components/cards/cardDate.css b/client/components/cards/cardDate.css index 30bc0d3af..4a873e485 100644 --- a/client/components/cards/cardDate.css +++ b/client/components/cards/cardDate.css @@ -8,57 +8,134 @@ .card-date.is-active { background-color: #b3b3b3; } -.card-date.current, -.card-date.almost-due, -.card-date.due, -.card-date.long-overdue { +/* Date status colors - red = overdue, amber = due soon, no shade = not due */ +.card-date.overdue { + background-color: #ff4444; /* Red for overdue */ color: #fff; } +.card-date.overdue:hover, +.card-date.overdue.is-active { + background-color: #cc3333; +} + +.card-date.due-soon { + background-color: #ffaa00; /* Amber for due soon */ + color: #000; +} +.card-date.due-soon:hover, +.card-date.due-soon.is-active { + background-color: #e69900; +} + +.card-date.not-due { + /* No special background - uses default date type colors */ +} + .card-date.current { - background-color: #5ba639; + background-color: #5ba639; /* Green for current/active */ + color: #fff; } .card-date.current:hover, .card-date.current.is-active { background-color: #46802c; } -.card-date.almost-due { - background-color: #edc909; + +.card-date.completed { + background-color: #90ee90; /* Light green for completed */ + color: #000; } -.card-date.almost-due:hover, -.card-date.almost-due.is-active { - background-color: #bc9f07; +.card-date.completed:hover, +.card-date.completed.is-active { + background-color: #7dd87d; } -.card-date.due { - background-color: #fa3f00; + +.card-date.completed-early { + background-color: #4caf50; /* Green for completed early */ + color: #fff; } -.card-date.due:hover, -.card-date.due.is-active { - background-color: #c73200; +.card-date.completed-early:hover, +.card-date.completed-early.is-active { + background-color: #45a049; } -.card-date.long-overdue { - background-color: #fd5d47; + +.card-date.completed-late { + background-color: #ff9800; /* Orange for completed late */ + color: #fff; } -.card-date.long-overdue:hover, -.card-date.long-overdue.is-active { - background-color: #fd3e24; +.card-date.completed-late:hover, +.card-date.completed-late.is-active { + background-color: #f57c00; +} + +.card-date.completed-on-time { + background-color: #2196f3; /* Blue for completed on time */ + color: #fff; +} +.card-date.completed-on-time:hover, +.card-date.completed-on-time.is-active { + background-color: #1976d2; +} + +/* Date type specific colors */ +.card-date.received-date { + background-color: #dbdbdb; /* Light grey for received */ +} + +.card-date.received-date:hover, +.card-date.received-date.is-active { + background-color: #b3b3b3; +} + +.card-date.start-date { + background-color: #90ee90; /* Light green for start */ + color: #000; /* Black text for start */ +} + +.card-date.start-date:hover, +.card-date.start-date.is-active { + background-color: #7dd87d; +} + +.card-date.due-date { + background-color: #ffd700; /* Yellow for due */ + color: #000; /* Black text for due */ +} + +.card-date.due-date:hover, +.card-date.due-date.is-active { + background-color: #e6c200; +} + +.card-date.end-date { + background-color: #ffb3b3; /* Light red for end */ + color: #000; /* Black text for end */ +} + +.card-date.end-date:hover, +.card-date.end-date.is-active { + background-color: #ff9999; } .card-date.end-date time::before { - content: "\f253"; + content: "🏁"; /* Finish flag - represents end/completion */ } .card-date.due-date time::before { - content: "\f090"; + content: "⏰"; /* Alarm clock - represents due/deadline */ } .card-date.start-date time::before { - content: "\f251"; + content: "🚀"; /* Rocket - represents start/launch */ } .card-date.received-date time::before { - content: "\f08b"; + content: "📥"; /* Inbox tray - represents received/incoming */ +} + +/* Generic date badge and custom field date */ +.card-date:not(.received-date):not(.start-date):not(.due-date):not(.end-date) time::before { + /*content: "📅"; // Calendar - represents generic date */ } .card-date time::before { - font: normal normal normal 14px/1 FontAwesome; font-size: inherit; - -webkit-font-smoothing: antialiased; margin-right: 0.3em; + display: inline-block; } .customfield-date { display: block; diff --git a/client/components/cards/cardDate.jade b/client/components/cards/cardDate.jade index 202b8f6f0..c8c6f45a3 100644 --- a/client/components/cards/cardDate.jade +++ b/client/components/cards/cardDate.jade @@ -21,3 +21,132 @@ template(name="dateCustomField") if showWeekOfYear b | {{showWeek}} + +template(name="minicardReceivedDate") + if canModifyCard + a.js-edit-date.card-date.received-date(title="{{_ 'card-received'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}") + time(datetime="{{showISODate}}") + | {{showDate}} + if showWeekOfYear + b + | {{showWeek}} + else + a.card-date.received-date(title="{{_ 'card-received'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}") + time(datetime="{{showISODate}}") + | {{showDate}} + if showWeekOfYear + b + | {{showWeek}} + +template(name="minicardStartDate") + if canModifyCard + a.js-edit-date.card-date.start-date(title="{{_ 'card-start'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}") + time(datetime="{{showISODate}}") + | {{showDate}} + if showWeekOfYear + b + | {{showWeek}} + else + a.card-date.start-date(title="{{_ 'card-start'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}") + time(datetime="{{showISODate}}") + | {{showDate}} + if showWeekOfYear + b + | {{showWeek}} + +template(name="minicardDueDate") + if canModifyCard + a.js-edit-date.card-date.due-date(title="{{_ 'card-due'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}") + time(datetime="{{showISODate}}") + | {{showDate}} + if showWeekOfYear + b + | {{showWeek}} + else + a.card-date.due-date(title="{{_ 'card-due'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}") + time(datetime="{{showISODate}}") + | {{showDate}} + if showWeekOfYear + b + | {{showWeek}} + +template(name="minicardEndDate") + if canModifyCard + a.js-edit-date.card-date.end-date(title="{{_ 'card-end'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}") + time(datetime="{{showISODate}}") + | {{showDate}} + if showWeekOfYear + b + | {{showWeek}} + else + a.card-date.end-date(title="{{_ 'card-end'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}") + time(datetime="{{showISODate}}") + | {{showDate}} + if showWeekOfYear + b + | {{showWeek}} + +template(name="minicardCustomFieldDate") + a(title="{{_ 'date'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}") + time(datetime="{{showISODate}}") + | {{showDate}} + if showWeekOfYear + b + | {{showWeek}} + +template(name="editCardReceivedDatePopup") + form.edit-card-received-date + .datepicker + // Date input field (existing) + // Insert calendar selector right after date input + .calendar-selector + label(for="calendar-received") 🗓️ + input#calendar-received.js-calendar-date(type="date") + // Time input field (if present) + .clear-date + a.js-clear-date {{_ 'clear'}} + .datepicker-actions + button.primary.wide.left(type="submit") {{_ 'save'}} + button.js-delete-date.negate.wide.right {{_ 'delete'}} + +template(name="editCardStartDatePopup") + form.edit-card-start-date + .datepicker + // Date input field (existing) + .calendar-selector + label(for="calendar-start") 🗓️ + input#calendar-start.js-calendar-date(type="date") + // Time input field (if present) + .clear-date + a.js-clear-date {{_ 'clear'}} + .datepicker-actions + button.primary.wide.left(type="submit") {{_ 'save'}} + button.js-delete-date.negate.wide.right {{_ 'delete'}} + +template(name="editCardDueDatePopup") + form.edit-card-due-date + .datepicker + // Date input field (existing) + .calendar-selector + label(for="calendar-due") 🗓️ + input#calendar-due.js-calendar-date(type="date") + // Time input field (if present) + .clear-date + a.js-clear-date {{_ 'clear'}} + .datepicker-actions + button.primary.wide.left(type="submit") {{_ 'save'}} + button.js-delete-date.negate.wide.right {{_ 'delete'}} + +template(name="editCardEndDatePopup") + form.edit-card-end-date + .datepicker + // Date input field (existing) + .calendar-selector + label(for="calendar-end") 🗓️ + input#calendar-end.js-calendar-date(type="date") + // Time input field (if present) + .clear-date + a.js-clear-date {{_ 'clear'}} + .datepicker-actions + button.primary.wide.left(type="submit") {{_ 'save'}} + button.js-delete-date.negate.wide.right {{_ 'delete'}} diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index 5d255614d..a470bbba4 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -1,17 +1,38 @@ -import moment from 'moment/min/moment-with-locales'; import { TAPi18n } from '/imports/i18n'; import { DatePicker } from '/client/lib/datepicker'; +import { + formatDateTime, + formatDate, + formatDateByUserPreference, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar, + diff +} from '/imports/lib/dateUtils'; // editCardReceivedDatePopup (class extends DatePicker { onCreated() { - super.onCreated(moment().format('YYYY-MM-DD HH:mm')); + super.onCreated(formatDateTime(now())); this.data().getReceived() && - this.date.set(moment(this.data().getReceived())); + this.date.set(new Date(this.data().getReceived())); } _storeDate(date) { - this.card.setReceived(moment(date).format('YYYY-MM-DD HH:mm')); + this.card.setReceived(formatDateTime(date)); } _deleteDate() { @@ -22,22 +43,28 @@ import { DatePicker } from '/client/lib/datepicker'; // editCardStartDatePopup (class extends DatePicker { onCreated() { - super.onCreated(moment().format('YYYY-MM-DD HH:mm')); - this.data().getStart() && this.date.set(moment(this.data().getStart())); + super.onCreated(formatDateTime(now())); + this.data().getStart() && this.date.set(new Date(this.data().getStart())); } onRendered() { super.onRendered(); - if (moment.isDate(this.card.getReceived())) { - this.$('.js-datepicker').datepicker( - 'setStartDate', - this.card.getReceived(), - ); - } + // DatePicker base class handles initialization with native HTML inputs + const self = this; + this.$('.js-calendar-date').on('change', function(evt) { + const currentUser = ReactiveCache.getCurrentUser && ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + const value = evt.target.value; + if (value) { + // Format date according to user preference + const formatted = formatDateByUserPreference(new Date(value), dateFormat, true); + self._storeDate(new Date(value)); + } + }); } _storeDate(date) { - this.card.setStart(moment(date).format('YYYY-MM-DD HH:mm')); + this.card.setStart(formatDateTime(date)); } _deleteDate() { @@ -49,18 +76,16 @@ import { DatePicker } from '/client/lib/datepicker'; (class extends DatePicker { onCreated() { super.onCreated('1970-01-01 17:00:00'); - this.data().getDue() && this.date.set(moment(this.data().getDue())); + this.data().getDue() && this.date.set(new Date(this.data().getDue())); } onRendered() { super.onRendered(); - if (moment.isDate(this.card.getStart())) { - this.$('.js-datepicker').datepicker('setStartDate', this.card.getStart()); - } + // DatePicker base class handles initialization with native HTML inputs } _storeDate(date) { - this.card.setDue(moment(date).format('YYYY-MM-DD HH:mm')); + this.card.setDue(formatDateTime(date)); } _deleteDate() { @@ -71,19 +96,17 @@ import { DatePicker } from '/client/lib/datepicker'; // editCardEndDatePopup (class extends DatePicker { onCreated() { - super.onCreated(moment().format('YYYY-MM-DD HH:mm')); - this.data().getEnd() && this.date.set(moment(this.data().getEnd())); + super.onCreated(formatDateTime(now())); + this.data().getEnd() && this.date.set(new Date(this.data().getEnd())); } onRendered() { super.onRendered(); - if (moment.isDate(this.card.getStart())) { - this.$('.js-datepicker').datepicker('setStartDate', this.card.getStart()); - } + // DatePicker base class handles initialization with native HTML inputs } _storeDate(date) { - this.card.setEnd(moment(date).format('YYYY-MM-DD HH:mm')); + this.card.setEnd(formatDateTime(date)); } _deleteDate() { @@ -100,27 +123,29 @@ const CardDate = BlazeComponent.extendComponent({ onCreated() { const self = this; self.date = ReactiveVar(); - self.now = ReactiveVar(moment()); + self.now = ReactiveVar(now()); window.setInterval(() => { - self.now.set(moment()); + self.now.set(now()); }, 60000); }, showWeek() { - return this.date.get().week().toString(); + return getISOWeek(this.date.get()).toString(); }, showWeekOfYear() { - return ReactiveCache.getCurrentUser().isShowWeekOfYear(); + const user = ReactiveCache.getCurrentUser(); + if (!user) { + // For non-logged-in users, week of year is not shown + return false; + } + return user.isShowWeekOfYear(); }, showDate() { - // this will start working once mquandalle:moment - // is updated to at least moment.js 2.10.5 - // until then, the date is displayed in the "L" format - return this.date.get().calendar(null, { - sameElse: 'llll', - }); + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + return formatDateByUserPreference(this.date.get(), dateFormat, true); }, showISODate() { @@ -133,7 +158,7 @@ class CardReceivedDate extends CardDate { super.onCreated(); const self = this; self.autorun(() => { - self.date.set(moment(self.data().getReceived())); + self.date.set(new Date(self.data().getReceived())); }); } @@ -143,21 +168,26 @@ class CardReceivedDate extends CardDate { const endAt = this.data().getEnd(); const startAt = this.data().getStart(); const theDate = this.date.get(); - // if dueAt, endAt and startAt exist & are > receivedAt, receivedAt doesn't need to be flagged + const now = this.now.get(); + + // Received date logic: if received date is after start, due, or end dates, it's overdue if ( - (startAt && theDate.isAfter(startAt)) || - (endAt && theDate.isAfter(endAt)) || - (dueAt && theDate.isAfter(dueAt)) - ) - classes += 'long-overdue'; - else classes += 'current'; + (startAt && isAfter(theDate, startAt)) || + (endAt && isAfter(theDate, endAt)) || + (dueAt && isAfter(theDate, dueAt)) + ) { + classes += 'overdue'; + } else { + classes += 'not-due'; + } return classes; } showTitle() { - return `${TAPi18n.__('card-received-on')} ${this.date - .get() - .format('LLLL')}`; + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + const formattedDate = formatDateByUserPreference(this.date.get(), dateFormat, true); + return `${TAPi18n.__('card-received-on')} ${formattedDate}`; } events() { @@ -173,26 +203,35 @@ class CardStartDate extends CardDate { super.onCreated(); const self = this; self.autorun(() => { - self.date.set(moment(self.data().getStart())); + self.date.set(new Date(self.data().getStart())); }); } classes() { - let classes = 'start-date' + ' '; + let classes = 'start-date '; const dueAt = this.data().getDue(); const endAt = this.data().getEnd(); const theDate = this.date.get(); const now = this.now.get(); - // if dueAt or endAt exist & are > startAt, startAt doesn't need to be flagged - if ((endAt && theDate.isAfter(endAt)) || (dueAt && theDate.isAfter(dueAt))) - classes += 'long-overdue'; - else if (theDate.isAfter(now)) classes += ''; - else classes += 'current'; + + // Start date logic: if start date is after due or end dates, it's overdue + if ((endAt && isAfter(theDate, endAt)) || (dueAt && isAfter(theDate, dueAt))) { + classes += 'overdue'; + } else if (isAfter(theDate, now)) { + // Start date is in the future - not due yet + classes += 'not-due'; + } else { + // Start date is today or in the past - current/active + classes += 'current'; + } return classes; } showTitle() { - return `${TAPi18n.__('card-start-on')} ${this.date.get().format('LLLL')}`; + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + const formattedDate = formatDateByUserPreference(this.date.get(), dateFormat, true); + return `${TAPi18n.__('card-start-on')} ${formattedDate}`; } events() { @@ -208,27 +247,48 @@ class CardDueDate extends CardDate { super.onCreated(); const self = this; self.autorun(() => { - self.date.set(moment(self.data().getDue())); + self.date.set(new Date(self.data().getDue())); }); } classes() { - let classes = 'due-date' + ' '; + let classes = 'due-date '; const endAt = this.data().getEnd(); const theDate = this.date.get(); const now = this.now.get(); - // if the due date is after the end date, green - done early - if (endAt && theDate.isAfter(endAt)) classes += 'current'; - // if there is an end date, don't need to flag the due date - else if (endAt) classes += ''; - else if (now.diff(theDate, 'days') >= 2) classes += 'long-overdue'; - else if (now.diff(theDate, 'minute') >= 0) classes += 'due'; - else if (now.diff(theDate, 'days') >= -1) classes += 'almost-due'; + + // If there's an end date and it's before the due date, task is completed early + if (endAt && isBefore(endAt, theDate)) { + classes += 'completed-early'; + } + // If there's an end date, don't show due date status since task is completed + else if (endAt) { + classes += 'completed'; + } + // Due date logic based on current time + else { + const daysDiff = diff(theDate, now, 'days'); + + if (daysDiff < 0) { + // Due date is in the past - overdue + classes += 'overdue'; + } else if (daysDiff <= 1) { + // Due today or tomorrow - due soon + classes += 'due-soon'; + } else { + // Due date is more than 1 day away - not due yet + classes += 'not-due'; + } + } + return classes; } showTitle() { - return `${TAPi18n.__('card-due-on')} ${this.date.get().format('LLLL')}`; + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + const formattedDate = formatDateByUserPreference(this.date.get(), dateFormat, true); + return `${TAPi18n.__('card-due-on')} ${formattedDate}`; } events() { @@ -244,22 +304,33 @@ class CardEndDate extends CardDate { super.onCreated(); const self = this; self.autorun(() => { - self.date.set(moment(self.data().getEnd())); + self.date.set(new Date(self.data().getEnd())); }); } classes() { - let classes = 'end-date' + ' '; + let classes = 'end-date '; const dueAt = this.data().getDue(); const theDate = this.date.get(); - if (!dueAt) classes += ''; - else if (theDate.isBefore(dueAt)) classes += 'current'; - else if (theDate.isAfter(dueAt)) classes += 'due'; + + if (!dueAt) { + // No due date set - just show as completed + classes += 'completed'; + } else if (isBefore(theDate, dueAt)) { + // End date is before due date - completed early + classes += 'completed-early'; + } else if (isAfter(theDate, dueAt)) { + // End date is after due date - completed late + classes += 'completed-late'; + } else { + // End date equals due date - completed on time + classes += 'completed-on-time'; + } return classes; } showTitle() { - return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`; + return `${TAPi18n.__('card-end-on')} ${format(this.date.get(), 'LLLL')}`; } events() { @@ -279,16 +350,21 @@ class CardCustomFieldDate extends CardDate { super.onCreated(); const self = this; self.autorun(() => { - self.date.set(moment(self.data().value)); + self.date.set(new Date(self.data().value)); }); } showWeek() { - return this.date.get().week().toString(); + return getISOWeek(this.date.get()).toString(); } showWeekOfYear() { - return ReactiveCache.getCurrentUser().isShowWeekOfYear(); + const user = ReactiveCache.getCurrentUser(); + if (!user) { + // For non-logged-in users, week of year is not shown + return false; + } + return user.isShowWeekOfYear(); } showDate() { @@ -301,7 +377,10 @@ class CardCustomFieldDate extends CardDate { } showTitle() { - return `${this.date.get().format('LLLL')}`; + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + const formattedDate = formatDateByUserPreference(this.date.get(), dateFormat, true); + return `${formattedDate}`; } classes() { @@ -315,32 +394,62 @@ class CardCustomFieldDate extends CardDate { CardCustomFieldDate.register('cardCustomFieldDate'); (class extends CardReceivedDate { + template() { + return 'minicardReceivedDate'; + } + showDate() { - return this.date.get().format('L'); + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + return formatDateByUserPreference(this.date.get(), dateFormat, true); } }.register('minicardReceivedDate')); (class extends CardStartDate { + template() { + return 'minicardStartDate'; + } + showDate() { - return this.date.get().format('YYYY-MM-DD HH:mm'); + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + return formatDateByUserPreference(this.date.get(), dateFormat, true); } }.register('minicardStartDate')); (class extends CardDueDate { + template() { + return 'minicardDueDate'; + } + showDate() { - return this.date.get().format('YYYY-MM-DD HH:mm'); + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + return formatDateByUserPreference(this.date.get(), dateFormat, true); } }.register('minicardDueDate')); (class extends CardEndDate { + template() { + return 'minicardEndDate'; + } + showDate() { - return this.date.get().format('YYYY-MM-DD HH:mm'); + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + return formatDateByUserPreference(this.date.get(), dateFormat, true); } }.register('minicardEndDate')); (class extends CardCustomFieldDate { + template() { + return 'minicardCustomFieldDate'; + } + showDate() { - return this.date.get().format('L'); + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + return formatDateByUserPreference(this.date.get(), dateFormat, true); } }.register('minicardCustomFieldDate')); @@ -349,7 +458,7 @@ class VoteEndDate extends CardDate { super.onCreated(); const self = this; self.autorun(() => { - self.date.set(moment(self.data().getVoteEnd())); + self.date.set(new Date(self.data().getVoteEnd())); }); } classes() { @@ -357,10 +466,12 @@ class VoteEndDate extends CardDate { return classes; } showDate() { - return this.date.get().format('L LT'); + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + return formatDateByUserPreference(this.date.get(), dateFormat, true); } showTitle() { - return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`; + return `${TAPi18n.__('card-end-on')} ${this.date.get().toLocaleString()}`; } events() { @@ -376,7 +487,7 @@ class PokerEndDate extends CardDate { super.onCreated(); const self = this; self.autorun(() => { - self.date.set(moment(self.data().getPokerEnd())); + self.date.set(new Date(self.data().getPokerEnd())); }); } classes() { @@ -384,10 +495,12 @@ class PokerEndDate extends CardDate { return classes; } showDate() { - return this.date.get().format('l LT'); + const currentUser = ReactiveCache.getCurrentUser(); + const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; + return formatDateByUserPreference(this.date.get(), dateFormat, true); } showTitle() { - return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`; + return `${TAPi18n.__('card-end-on')} ${format(this.date.get(), 'LLLL')}`; } events() { diff --git a/client/components/cards/cardDetails.css b/client/components/cards/cardDetails.css index 2f2522f5c..fb68b2957 100644 --- a/client/components/cards/cardDetails.css +++ b/client/components/cards/cardDetails.css @@ -1,11 +1,39 @@ +/* Date Format Selector */ +.card-details-item-date-format { + margin-bottom: 10px; +} + +.card-details-item-date-format .card-details-item-title { + font-size: 14px; + font-weight: bold; + margin-bottom: 5px; + color: #333; +} + +.card-details-item-date-format .js-date-format-selector { + width: 100%; + padding: 8px; + border: 1px solid #ddd; + border-radius: 4px; + background-color: #fff; + font-size: 14px; + cursor: pointer; +} + +.card-details-item-date-format .js-date-format-selector:focus { + outline: none; + border-color: #007cba; + box-shadow: 0 0 0 2px rgba(0, 124, 186, 0.2); +} + .assignee { - border-radius: 0.4vw; + border-radius: 3px; display: block; position: relative; float: left; - height: 4vw; - width: 4vw; - margin: 0.4vh; + height: 30px; + width: 30px; + margin: .3vh; cursor: pointer; user-select: none; z-index: 1; @@ -34,11 +62,11 @@ background-color: #b3b3b3; border: 1px solid #fff; border-radius: 50%; - height: 1vw; - width: 1vw; + height: 7px; + width: 7px; position: absolute; - right: -0.1vw; - bottom: -0.1vw; + right: -1px; + bottom: -1px; border: 1px solid #fff; z-index: 15; } diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 043eca308..cf810b38a 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -12,15 +12,19 @@ template(name="cardDetails") else unless isMiniScreen unless isPopup - a.fa.fa-times-thin.close-card-details.js-close-card-details(title="{{_ 'close-card'}}") + a.close-card-details.js-close-card-details(title="{{_ 'close-card'}}") + | ❌ if canModifyCard if cardMaximized - a.fa.fa-window-minimize.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}") + a.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}") + | 🔽 else - a.fa.fa-window-maximize.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}") + a.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}") + | 🔼 if canModifyCard - a.fa.fa-navicon.card-details-menu.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") - a.fa.fa-link.card-copy-button.js-copy-link( + a.card-details-menu.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") + | ☰ + a.card-copy-button.js-copy-link( id="cardURL_copy" class="fa-link" title="{{_ 'copy-card-link-to-clipboard'}}" @@ -29,10 +33,12 @@ template(name="cardDetails") span.copied-tooltip {{_ 'copied'}} else unless isPopup - a.fa.fa-times-thin.close-card-details.js-close-card-details(title="{{_ 'close-card'}}") + a.close-card-details.js-close-card-details(title="{{_ 'close-card'}}") + | ❌ if canModifyCard - a.fa.fa-navicon.card-details-menu-mobile-web.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") - a.fa.fa-link.card-copy-mobile-button.js-copy-link( + a.card-details-menu-mobile-web.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") + | ☰ + a.card-copy-mobile-button.js-copy-link( id="cardURL_copy" class="fa-link" title="{{_ 'copy-card-link-to-clipboard'}}" @@ -47,7 +53,8 @@ template(name="cardDetails") | ##{getCardNumber} = getTitle if isWatching - i.card-details-watch.fa.fa-eye + i.card-details-watch + | 👁️ .card-details-path each parentList |   >   @@ -69,7 +76,7 @@ template(name="cardDetails") if hasActiveUploads .card-details-upload-progress .upload-progress-header - i.fa.fa-upload + | 📤 span {{_ 'uploading-files'}} ({{uploadCount}}) each uploads .upload-progress-item(class="{{#if $eq status 'error'}}upload-error{{/if}}") @@ -78,11 +85,11 @@ template(name="cardDetails") .upload-progress-fill(style="width: {{progress}}%") if $eq status 'error' .upload-progress-error - i.fa.fa-exclamation-triangle + | ⚠️ span {{_ 'upload-failed'}} else if $eq status 'completed' .upload-progress-success - i.fa.fa-check + | ✅ span {{_ 'upload-completed'}} .card-details-left @@ -91,7 +98,7 @@ template(name="cardDetails") 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 @@ -101,15 +108,25 @@ template(name="cardDetails") if canModifyCard unless currentUser.isWorker a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}") - i.fa.fa-plus + | ➕ if currentBoard.hasAnyAllowsDate hr + .card-details-item.card-details-item-date-format + h3.card-details-item-title + | 📅 + | {{_ 'date-format'}} + .card-details-item-content + select.js-date-format-selector + option(value="YYYY-MM-DD" selected="{{#if isDateFormat 'YYYY-MM-DD'}}selected{{/if}}") {{_ 'date-format-yyyy-mm-dd'}} + option(value="DD-MM-YYYY" selected="{{#if isDateFormat 'DD-MM-YYYY'}}selected{{/if}}") {{_ 'date-format-dd-mm-yyyy'}} + option(value="MM-DD-YYYY" selected="{{#if isDateFormat 'MM-DD-YYYY'}}selected{{/if}}") {{_ 'date-format-mm-dd-yyyy'}} + if currentBoard.allowsReceivedDate .card-details-item.card-details-item-received h3.card-details-item-title - i.fa.fa-sign-out + | 📥 | {{_ 'card-received'}} if getReceived +cardReceivedDate @@ -117,12 +134,12 @@ template(name="cardDetails") 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 @@ -130,12 +147,12 @@ template(name="cardDetails") 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 @@ -143,12 +160,12 @@ template(name="cardDetails") 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 @@ -156,7 +173,7 @@ template(name="cardDetails") if canModifyCard unless currentUser.isWorker a.card-label.add-label.js-end-date - i.fa.fa-plus + | ➕ if currentBoard.hasAnyAllowsUser hr @@ -164,7 +181,7 @@ template(name="cardDetails") 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) @@ -174,7 +191,7 @@ template(name="cardDetails") 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) @@ -182,30 +199,30 @@ template(name="cardDetails") 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 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 @@ -225,7 +242,7 @@ template(name="cardDetails") 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 @@ -248,7 +265,7 @@ template(name="cardDetails") 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") @@ -261,7 +278,7 @@ template(name="cardDetails") if currentBoard.allowsShowLists .card-details-item.card-details-show-lists h3.card-details-item-title - i.fa.fa-list + | 📋 | {{_ 'list'}} select.js-select-card-details-lists(disabled="{{#unless canModifyCard}}disabled{{/unless}}") each currentBoard.lists @@ -287,7 +304,7 @@ template(name="cardDetails") hr .card-details-item.card-details-item-customfield h3.card-details-item-title - i.fa.fa-list-alt + | 📋-alt = definition.name +cardCustomField @@ -298,14 +315,14 @@ template(name="cardDetails") else input.toggle-switch(type="checkbox" id="toggleCustomFieldsGridButton") label.toggle-label(for="toggleCustomFieldsGridButton") - a.fa.fa-plus.js-custom-fields.card-details-item.custom-fields(title="{{_ 'custom-fields'}}") + a.js-custom-fields.card-details-item.custom-fields(title="{{_ 'custom-fields'}}") if getVoteQuestion hr .vote-title div.flex h3 - i.fa.fa-thumbs-up + | 👍 | {{_ 'vote-question'}} if getVoteEnd +voteEndDate @@ -323,11 +340,11 @@ template(name="cardDetails") 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 @@ -335,7 +352,7 @@ template(name="cardDetails") .poker-title div.flex h3 - i.fa.fa-thumbs-up + | 👍 | {{_ 'poker-question'}} if getPokerEnd +pokerEndDate @@ -350,52 +367,52 @@ template(name="cardDetails") .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'}} @@ -525,7 +542,7 @@ template(name="cardDetails") 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") @@ -535,18 +552,18 @@ template(name="cardDetails") 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 + a.js-close-inlined-form else if currentBoard.allowsDescriptionText a.js-open-inlined-form(title="{{_ 'edit'}}" value=title) - i.fa.fa-pencil-square-o + | ✏️ a.js-open-inlined-form(title="{{_ 'edit'}}" value=title) if getDescription +viewer @@ -576,7 +593,7 @@ template(name="cardDetails") if currentBoard.allowsAttachments hr h3.card-details-item-title - i.fa.fa-paperclip + | 📎 | {{_ 'attachments'}} if Meteor.settings.public.attachmentsUploadMaxSize | {{_ 'max-upload-filesize'}} {{Meteor.settings.public.attachmentsUploadMaxSize}} @@ -592,7 +609,7 @@ template(name="cardDetails") unless currentUser.isNoComments .comment-title h3.card-details-item-title - i.fa.fa-comment-o + | 💬 | {{_ 'comments'}} if currentBoard.allowsComments @@ -607,7 +624,7 @@ template(name="cardDetails") unless currentUser.isNoComments .activity-title h3.card-details-item-title - i.fa.fa-history + | 📜 | {{ _ 'activities'}} if currentUser.isBoardMember .material-toggle-switch(title="{{_ 'show-activities'}}") @@ -627,41 +644,41 @@ template(name="cardDetails") +activities(card=this mode="card") template(name="editCardTitleForm") - a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}") + a(title="{{_ 'copy-text-to-clipboard'}}") span.copied-tooltip {{_ 'copied'}} textarea.js-edit-card-title(rows='1' autofocus dir="auto") = getTitle .edit-controls.clearfix button.primary.confirm.js-submit-edit-card-title-form(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form template(name="editCardRequesterForm") input.js-edit-card-requester(type='text' autofocus value=getRequestedBy dir="auto") .edit-controls.clearfix button.primary.confirm.js-submit-edit-card-requester-form(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form template(name="editCardAssignerForm") input.js-edit-card-assigner(type='text' autofocus value=getAssignedBy dir="auto") .edit-controls.clearfix button.primary.confirm.js-submit-edit-card-assigner-form(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.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 + a.js-close-inlined-form template(name="cardDetailsActionsPopup") ul.pop-over-list li a.js-toggle-watch-card if isWatching - i.fa.fa-eye + | 👁️ | {{_ 'unwatch'}} else - i.fa.fa-eye-slash + | 👁️-slash | {{_ 'watch'}} hr if canModifyCard @@ -672,16 +689,16 @@ template(name="cardDetailsActionsPopup") //li: a.js-attachments {{_ 'card-edit-attachments'}} li a.js-start-voting - i.fa.fa-thumbs-up + | 👍 | {{_ 'card-edit-voting'}} li a.js-start-planning-poker - i.fa.fa-thumbs-up + | 👍 | {{_ 'card-edit-planning-poker'}} if currentUser.isBoardAdmin li a.js-custom-fields - i.fa.fa-list-alt + | 📋-alt | {{_ 'card-edit-custom-fields'}} //li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}} //li: a.js-start-date {{_ 'editCardStartDatePopup-title'}} @@ -689,75 +706,75 @@ template(name="cardDetailsActionsPopup") //li: a.js-end-date {{_ 'editCardEndDatePopup-title'}} li a.js-spent-time - i.fa.fa-clock-o + | 🕐 | {{_ 'editCardSpentTimePopup-title'}} li a.js-set-card-color - i.fa.fa-paint-brush + | 🎨 | {{_ 'setCardColorPopup-title'}} li a.js-toggle-show-list-on-minicard if showListOnMinicard - i.fa.fa-eye + | 👁️ | {{_ 'hide-list-on-minicard'}} else - i.fa.fa-eye-slash + | 👁️-slash | {{_ 'show-list-on-minicard'}} 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 - i.fa.fa-arrow-right + | ➡️ | {{_ 'moveCardPopup-title'}} unless currentUser.isWorker li a.js-copy-card - i.fa.fa-copy + | 📋 | {{_ 'copyCardPopup-title'}} unless currentUser.isWorker ul.pop-over-list li a.js-copy-checklist-cards - i.fa.fa-copy - i.fa.fa-copy + | 📋 + | 📋 | {{_ 'copyManyCardsPopup-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'}} template(name="exportCardPopup") ul.pop-over-list li a(href="{{exportUrlCardPDF}}",, download="{{exportFilenameCardPDF}}") - i.fa.fa-share-alt + | 📤 | {{_ 'export-card-pdf'}} template(name="moveCardPopup") @@ -812,7 +829,7 @@ template(name="cardMembersPopup") = user.profile.fullname | ({{ user.username }}) if isCardMember - i.fa.fa-check + | ✅ template(name="cardAssigneesPopup") input.card-assignees-filter(type="text" placeholder="{{_ 'search'}}") @@ -826,7 +843,7 @@ template(name="cardAssigneesPopup") = user.profile.fullname | ({{ user.username }}) if isCardAssignee - i.fa.fa-check + | ✅ if currentUser.isWorker ul.pop-over-list.js-card-assignee-list li.item(class="{{#if currentUser.isCardAssignee}}active{{/if}}") @@ -836,7 +853,7 @@ template(name="cardAssigneesPopup") = currentUser.profile.fullname | ({{ currentUser.username }}) if currentUser.isCardAssignee - i.fa.fa-check + | ✅ template(name="cardAssigneePopup") .board-assignee-menu @@ -860,7 +877,7 @@ template(name="cardMorePopup") span.clearfix span {{_ 'link-card'}} = ' ' - i.fa.colorful(class="{{#if board.isPublic}}fa-globe{{else}}fa-lock{{/if}}") + | {{#if board.isPublic}}🌐{{else}}🔒{{/if}} input.inline-input(type="text" id="cardURL" readonly value="{{ originRelativeUrl }}" autofocus="autofocus") button.js-copy-card-link-to-clipboard(class="btn" id="clipboard") {{_ 'copy-card-link-to-clipboard'}} .copied-tooltip {{_ 'copied'}} @@ -902,7 +919,7 @@ template(name="setCardColorPopup") unless $eq color 'white' span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") if(isSelected color) - i.fa.fa-check + | ✅ button.primary.confirm.js-submit {{_ 'save'}} button.js-remove-color.negate.wide.right {{_ 'unset-color'}} @@ -936,12 +953,12 @@ template(name="cardStartVotingPopup") .materialCheckBox#vote-public(name="vote-public" class="{{#if votePublic}}is-checked{{/if}}") span {{_ 'vote-public'}} .check-div.flex - i.fa.fa-hourglass-end + | ⏰ a.js-end-date span | {{_ 'card-end'}} unless getVoteEnd - i.fa.fa-plus + | ➕ if getVoteEnd +voteEndDate @@ -982,12 +999,12 @@ template(name="cardStartPlanningPokerPopup") .materialCheckBox#poker-allow-non-members(name="poker-allow-non-members" class="{{#if pokerAllowNonBoardMembers}}is-checked{{/if}}") span {{_ 'allowNonBoardMembers'}} .check-div.flex - i.fa.fa-hourglass-end + | ⏰ a.js-end-date span | {{_ 'card-end'}} unless getPokerEnd - i.fa.fa-plus + | ➕ if getPokerEnd +pokerEndDate diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index b6e62c740..43ee28473 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -1,7 +1,26 @@ import { ReactiveCache } from '/imports/reactiveCache'; -import moment from 'moment/min/moment-with-locales'; import { TAPi18n } from '/imports/i18n'; import { DatePicker } from '/client/lib/datepicker'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; import Cards from '/models/cards'; import Boards from '/models/boards'; import Checklists from '/models/checklists'; @@ -287,6 +306,10 @@ BlazeComponent.extendComponent({ const $tooltip = this.$('.card-details-header .copied-tooltip'); Utils.showCopied(promise, $tooltip); }, + 'change .js-date-format-selector'(event) { + const dateFormat = event.target.value; + Meteor.call('changeDateFormat', dateFormat); + }, 'click .js-open-card-details-menu': Popup.open('cardDetailsActions'), 'submit .js-card-description'(event) { event.preventDefault(); @@ -407,56 +430,57 @@ BlazeComponent.extendComponent({ ) { newState = forIt; } - this.data().setVote(Meteor.userId(), newState); + // Use secure server method; direct client updates to vote are blocked + Meteor.call('cards.vote', this.data()._id, newState); }, 'click .js-poker'(e) { let newState = null; if ($(e.target).hasClass('js-poker-vote-one')) { newState = 'one'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } if ($(e.target).hasClass('js-poker-vote-two')) { newState = 'two'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } if ($(e.target).hasClass('js-poker-vote-three')) { newState = 'three'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } if ($(e.target).hasClass('js-poker-vote-five')) { newState = 'five'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } if ($(e.target).hasClass('js-poker-vote-eight')) { newState = 'eight'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } if ($(e.target).hasClass('js-poker-vote-thirteen')) { newState = 'thirteen'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } if ($(e.target).hasClass('js-poker-vote-twenty')) { newState = 'twenty'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } if ($(e.target).hasClass('js-poker-vote-forty')) { newState = 'forty'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } if ($(e.target).hasClass('js-poker-vote-one-hundred')) { newState = 'oneHundred'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } if ($(e.target).hasClass('js-poker-vote-unsure')) { newState = 'unsure'; - this.data().setPoker(Meteor.userId(), newState); + Meteor.call('cards.pokerVote', this.data()._id, newState); } }, 'click .js-poker-finish'(e) { if ($(e.target).hasClass('js-poker-finish')) { e.preventDefault(); - const now = moment().format('YYYY-MM-DD HH:mm'); - this.data().setPokerEnd(now); + const now = new Date(); + Meteor.call('cards.setPokerEnd', this.data()._id, now); } }, @@ -464,9 +488,9 @@ BlazeComponent.extendComponent({ if ($(e.target).hasClass('js-poker-replay')) { e.preventDefault(); this.currentCard = this.currentData(); - this.currentCard.replayPoker(); - this.data().unsetPokerEnd(); - this.data().unsetPokerEstimation(); + Meteor.call('cards.replayPoker', this.currentCard._id); + Meteor.call('cards.unsetPokerEnd', this.currentCard._id); + Meteor.call('cards.unsetPokerEstimation', this.currentCard._id); } }, 'click .js-poker-estimation'(event) { @@ -477,63 +501,66 @@ BlazeComponent.extendComponent({ this.find('#pokerEstimation').value = ''; if (ruleTitle) { - this.data().setPokerEstimation(parseInt(ruleTitle, 10)); + Meteor.call('cards.setPokerEstimation', this.data()._id, parseInt(ruleTitle, 10)); } else { - this.data().setPokerEstimation(''); + Meteor.call('cards.unsetPokerEstimation', this.data()._id); } } }, // Drag and drop file upload handlers 'dragover .js-card-details'(event) { - event.preventDefault(); - event.stopPropagation(); + // Only prevent default for file drags to avoid interfering with other drag operations + const dataTransfer = event.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + event.stopPropagation(); + } }, 'dragenter .js-card-details'(event) { - event.preventDefault(); - event.stopPropagation(); - const card = this.data(); - const board = card.board(); - // Only allow drag-and-drop if user can modify card and board allows attachments - if (card.canModifyCard() && board && board.allowsAttachments) { - // Check if the drag contains files - const dataTransfer = event.originalEvent.dataTransfer; - if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + const dataTransfer = event.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + event.stopPropagation(); + const card = this.data(); + const board = card.board(); + // Only allow drag-and-drop if user can modify card and board allows attachments + if (Utils.canModifyCard() && board && board.allowsAttachments) { $(event.currentTarget).addClass('is-dragging-over'); } } }, 'dragleave .js-card-details'(event) { - event.preventDefault(); - event.stopPropagation(); - $(event.currentTarget).removeClass('is-dragging-over'); + const dataTransfer = event.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + event.stopPropagation(); + $(event.currentTarget).removeClass('is-dragging-over'); + } }, 'drop .js-card-details'(event) { - event.preventDefault(); - event.stopPropagation(); - $(event.currentTarget).removeClass('is-dragging-over'); - - const card = this.data(); - const board = card.board(); - - // Check permissions - if (!card.canModifyCard() || !board || !board.allowsAttachments) { - return; - } - - // Check if this is a file drop (not a checklist item reorder) const dataTransfer = event.originalEvent.dataTransfer; - if (!dataTransfer || !dataTransfer.files || dataTransfer.files.length === 0) { - return; - } + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + event.stopPropagation(); + $(event.currentTarget).removeClass('is-dragging-over'); - // Check if the drop contains files (not just text/HTML) - if (!dataTransfer.types.includes('Files')) { - return; - } + const card = this.data(); + const board = card.board(); - const files = dataTransfer.files; - if (files && files.length > 0) { - handleFileUpload(card, files); + // Check permissions + if (!Utils.canModifyCard() || !board || !board.allowsAttachments) { + return; + } + + // Check if this is a file drop (not a checklist item reorder) + if (!dataTransfer.files || dataTransfer.files.length === 0) { + return; + } + + const files = dataTransfer.files; + if (files && files.length > 0) { + handleFileUpload(card, files); + } } }, }, @@ -546,6 +573,11 @@ Template.cardDetails.helpers({ let ret = !!Utils.getPopupCardId(); return ret; }, + isDateFormat(format) { + const currentUser = ReactiveCache.getCurrentUser(); + if (!currentUser) return format === 'YYYY-MM-DD'; + return currentUser.getDateFormat() === format; + }, // Upload progress helpers hasActiveUploads() { return uploadProgressManager.hasActiveUploads(this._id); @@ -1074,20 +1106,15 @@ BlazeComponent.extendComponent({ 'is-checked', ); const endString = this.currentCard.getVoteEnd(); - - this.currentCard.setVoteQuestion( - voteQuestion, - publicVote, - allowNonBoardMembers, - ); + Meteor.call('cards.setVoteQuestion', this.currentCard._id, voteQuestion, publicVote, allowNonBoardMembers); if (endString) { - this.currentCard.setVoteEnd(endString); + Meteor.call('cards.setVoteEnd', this.currentCard._id, endString); } Popup.back(); }, 'click .js-remove-vote': Popup.afterConfirm('deleteVote', () => { event.preventDefault(); - this.currentCard.unsetVote(); + Meteor.call('cards.unsetVote', this.currentCard._id); Popup.back(); }), 'click a.js-toggle-vote-public'(event) { @@ -1106,8 +1133,8 @@ BlazeComponent.extendComponent({ // editVoteEndDatePopup (class extends DatePicker { onCreated() { - super.onCreated(moment().format('YYYY-MM-DD HH:mm')); - this.data().getVoteEnd() && this.date.set(moment(this.data().getVoteEnd())); + super.onCreated(formatDateTime(now())); + this.data().getVoteEnd() && this.date.set(new Date(this.data().getVoteEnd())); } events() { return [ @@ -1118,12 +1145,12 @@ BlazeComponent.extendComponent({ // if no time was given, init with 12:00 const time = evt.target.time.value || - moment(new Date().setHours(12, 0, 0)).format('LT'); + formatTime(new Date().setHours(12, 0, 0)); const dateString = `${evt.target.date.value} ${time}`; /* - const newDate = moment(dateString, 'L LT', true); + const newDate = parseDate(dateString, ['L LT'], true); if (newDate.isValid()) { // if active vote - store it if (this.currentData().getVoteQuestion()) { @@ -1137,28 +1164,27 @@ BlazeComponent.extendComponent({ */ - // Try to parse different date formats of all languages. - // This code is same for vote and planning poker. - const usaDate = moment(dateString, 'L LT', true); - const euroAmDate = moment(dateString, 'DD.MM.YYYY LT', true); - const euro24hDate = moment(dateString, 'DD.MM.YYYY HH.mm', true); - const eurodotDate = moment(dateString, 'DD.MM.YYYY HH:mm', true); - const minusDate = moment(dateString, 'YYYY-MM-DD HH:mm', true); - const slashDate = moment(dateString, 'DD/MM/YYYY HH.mm', true); - const dotDate = moment(dateString, 'DD/MM/YYYY HH:mm', true); - const brezhonegDate = moment(dateString, 'DD/MM/YYYY h[e]mm A', true); - const hrvatskiDate = moment(dateString, 'DD. MM. YYYY H:mm', true); - const latviaDate = moment(dateString, 'YYYY.MM.DD. H:mm', true); - const nederlandsDate = moment(dateString, 'DD-MM-YYYY HH:mm', true); - // greekDate does not work: el Greek Ελληνικά , - // it has date format DD/MM/YYYY h:mm MM like 20/06/2021 11:15 MM - // where MM is maybe some text like AM/PM ? - // Also some other languages that have non-ascii characters in dates - // do not work. - const greekDate = moment(dateString, 'DD/MM/YYYY h:mm A', true); - const macedonianDate = moment(dateString, 'D.MM.YYYY H:mm', true); + // Try to parse different date formats using native Date parsing + const formats = [ + 'YYYY-MM-DD HH:mm', + 'MM/DD/YYYY HH:mm', + 'DD.MM.YYYY HH:mm', + 'DD/MM/YYYY HH:mm', + 'DD-MM-YYYY HH:mm' + ]; + + let parsedDate = null; + for (const format of formats) { + parsedDate = parseDate(dateString, [format], true); + if (parsedDate) break; + } + + // Fallback to native Date parsing + if (!parsedDate) { + parsedDate = new Date(dateString); + } - if (usaDate.isValid()) { + if (isValidDate(parsedDate)) { // if active poker - store it if (this.currentData().getPokerQuestion()) { this._storeDate(usaDate.toDate()); @@ -1287,10 +1313,10 @@ BlazeComponent.extendComponent({ ]; } _storeDate(newDate) { - this.card.setVoteEnd(newDate); + Meteor.call('cards.setVoteEnd', this.card._id, newDate); } _deleteDate() { - this.card.unsetVoteEnd(); + Meteor.call('cards.unsetVoteEnd', this.card._id); } }.register('editVoteEndDatePopup')); @@ -1312,17 +1338,14 @@ BlazeComponent.extendComponent({ ); const endString = this.currentCard.getPokerEnd(); - this.currentCard.setPokerQuestion( - pokerQuestion, - allowNonBoardMembers, - ); + Meteor.call('cards.setPokerQuestion', this.currentCard._id, pokerQuestion, allowNonBoardMembers); if (endString) { - this.currentCard.setPokerEnd(endString); + Meteor.call('cards.setPokerEnd', this.currentCard._id, new Date(endString)); } Popup.back(); }, 'click .js-remove-poker': Popup.afterConfirm('deletePoker', (event) => { - this.currentCard.unsetPoker(); + Meteor.call('cards.unsetPoker', this.currentCard._id); Popup.back(); }), 'click a.js-toggle-poker-allow-non-members'(event) { @@ -1337,9 +1360,9 @@ BlazeComponent.extendComponent({ // editPokerEndDatePopup (class extends DatePicker { onCreated() { - super.onCreated(moment().format('YYYY-MM-DD HH:mm')); + super.onCreated(formatDateTime(now())); this.data().getPokerEnd() && - this.date.set(moment(this.data().getPokerEnd())); + this.date.set(new Date(this.data().getPokerEnd())); } /* @@ -1357,7 +1380,7 @@ BlazeComponent.extendComponent({ return moment.localeData().longDateFormat('LT'); } - const newDate = moment(dateString, dateformat() + ' ' + timeformat(), true); + const newDate = parseDate(dateString, [dateformat() + ' ' + timeformat()], true); */ events() { @@ -1369,7 +1392,7 @@ BlazeComponent.extendComponent({ // if no time was given, init with 12:00 const time = evt.target.time.value || - moment(new Date().setHours(12, 0, 0)).format('LT'); + formatTime(new Date().setHours(12, 0, 0)); const dateString = `${evt.target.date.value} ${time}`; @@ -1380,7 +1403,7 @@ BlazeComponent.extendComponent({ Maybe client/components/lib/datepicker.jade could have hidden input field for datepicker format that could be used to detect date format? - const newDate = moment(dateString, dateformat() + ' ' + timeformat(), true); + const newDate = parseDate(dateString, [dateformat() + ' ' + timeformat()], true); if (newDate.isValid()) { // if active poker - store it @@ -1393,28 +1416,27 @@ BlazeComponent.extendComponent({ } */ - // Try to parse different date formats of all languages. - // This code is same for vote and planning poker. - const usaDate = moment(dateString, 'L LT', true); - const euroAmDate = moment(dateString, 'DD.MM.YYYY LT', true); - const euro24hDate = moment(dateString, 'DD.MM.YYYY HH.mm', true); - const eurodotDate = moment(dateString, 'DD.MM.YYYY HH:mm', true); - const minusDate = moment(dateString, 'YYYY-MM-DD HH:mm', true); - const slashDate = moment(dateString, 'DD/MM/YYYY HH.mm', true); - const dotDate = moment(dateString, 'DD/MM/YYYY HH:mm', true); - const brezhonegDate = moment(dateString, 'DD/MM/YYYY h[e]mm A', true); - const hrvatskiDate = moment(dateString, 'DD. MM. YYYY H:mm', true); - const latviaDate = moment(dateString, 'YYYY.MM.DD. H:mm', true); - const nederlandsDate = moment(dateString, 'DD-MM-YYYY HH:mm', true); - // greekDate does not work: el Greek Ελληνικά , - // it has date format DD/MM/YYYY h:mm MM like 20/06/2021 11:15 MM - // where MM is maybe some text like AM/PM ? - // Also some other languages that have non-ascii characters in dates - // do not work. - const greekDate = moment(dateString, 'DD/MM/YYYY h:mm A', true); - const macedonianDate = moment(dateString, 'D.MM.YYYY H:mm', true); + // Try to parse different date formats using native Date parsing + const formats = [ + 'YYYY-MM-DD HH:mm', + 'MM/DD/YYYY HH:mm', + 'DD.MM.YYYY HH:mm', + 'DD/MM/YYYY HH:mm', + 'DD-MM-YYYY HH:mm' + ]; + + let parsedDate = null; + for (const format of formats) { + parsedDate = parseDate(dateString, [format], true); + if (parsedDate) break; + } + + // Fallback to native Date parsing + if (!parsedDate) { + parsedDate = new Date(dateString); + } - if (usaDate.isValid()) { + if (isValidDate(parsedDate)) { // if active poker - store it if (this.currentData().getPokerQuestion()) { this._storeDate(usaDate.toDate()); @@ -1544,10 +1566,10 @@ BlazeComponent.extendComponent({ ]; } _storeDate(newDate) { - this.card.setPokerEnd(newDate); + Meteor.call('cards.setPokerEnd', this.card._id, newDate); } _deleteDate() { - this.card.unsetPokerEnd(); + Meteor.call('cards.unsetPokerEnd', this.card._id); } }.register('editPokerEndDatePopup')); diff --git a/client/components/cards/cardTime.jade b/client/components/cards/cardTime.jade index 8af8c4143..88f52fef6 100644 --- a/client/components/cards/cardTime.jade +++ b/client/components/cards/cardTime.jade @@ -15,8 +15,8 @@ template(name="editCardSpentTime") template(name="timeBadge") if canModifyCard - a.js-edit-time.card-time(title="{{showTitle}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}") - | {{showTime}} + a.js-edit-time.card-time(title="{{_ 'time'}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}") + | ⏱️ {{showTime}} else - a.card-time(title="{{showTitle}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}") - | {{showTime}} + a.card-time(title="{{_ 'time'}}" class="{{#if getIsOvertime}}card-label-red{{else}}card-label-green{{/if}}") + | ⏱️ {{showTime}} diff --git a/client/components/cards/checklists.css b/client/components/cards/checklists.css index 6b8c7e8f9..566df27f0 100644 --- a/client/components/cards/checklists.css +++ b/client/components/cards/checklists.css @@ -72,6 +72,10 @@ textarea.js-edit-checklist-item { padding-top: 3px; float: left; } +.checklist-title span.fa.checklist-handle.fa-arrows::before { + content: "↕️" !important; + font-family: inherit !important; +} #card-details-overlay { top: 0; bottom: -600px; @@ -148,6 +152,10 @@ textarea.js-edit-checklist-item { padding-top: 2px; padding-right: 10px; } +.checklist-item span.fa.checklistitem-handle.fa-arrows::before { + content: "↕️" !important; + font-family: inherit !important; +} .js-delete-checklist-item, .js-convert-checklist-item-to-card { margin: 0 0 0.5em 1.33em; diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index e943e338f..39ed211b1 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -1,14 +1,14 @@ template(name="checklists") .checklists-title h3.card-details-item-title - i.fa.fa-check + | ✅ | {{_ 'checklists'}} if canModifyCard +inlinedForm(autoclose=false classNames="js-add-checklist" cardId = cardId position="top") +addChecklistItemForm else a.add-checklist-top.js-open-inlined-form(title="{{_ 'add-checklist'}}") - i.fa.fa-plus + | ➕ if currentUser.isBoardMember .material-toggle-switch(title="{{_ 'hide-finished-checklist'}}") //span.toggle-switch-title @@ -28,7 +28,7 @@ template(name="checklists") +addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=false) else a.add-checklist.js-open-inlined-form(title="{{_ 'add-checklist'}}") - i.fa.fa-plus + | ➕ template(name="checklistDetail") .js-checklist.checklist.nodragscroll @@ -38,7 +38,7 @@ template(name="checklistDetail") .checklist-title span if canModifyCard - a.fa.fa-navicon.checklist-details-menu.js-open-checklist-details-menu(title="{{_ 'checklistActionsPopup-title'}}") + a.checklist-details-menu.js-open-checklist-details-menu(title="{{_ 'checklistActionsPopup-title'}}") if canModifyCard h4.title.js-open-inlined-form.is-editable @@ -63,12 +63,13 @@ template(name="checklistDeletePopup") button.js-confirm.negate.full(type="submit") {{_ 'delete'}} template(name="addChecklistItemForm") - a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}") + a(title="{{_ 'copy-text-to-clipboard'}}") span.copied-tooltip {{_ 'copied'}} textarea.js-add-checklist-item(rows='1' autofocus) .edit-controls.clearfix button.primary.confirm.js-submit-add-checklist-item-form(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form(title="{{_ 'close-add-checklist-item'}}") + a.js-close-inlined-form(title="{{_ 'close-add-checklist-item'}}") + | ❌ if showNewlineBecomesNewChecklistItem .material-toggle-switch(title="{{_ 'newlineBecomesNewChecklistItem'}}") input.toggle-switch(type="checkbox" id="toggleNewlineBecomesNewChecklistItem") @@ -81,7 +82,7 @@ template(name="addChecklistItemForm") | {{_ 'originOrder'}} template(name="editChecklistItemForm") - a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}") + a(title="{{_ 'copy-text-to-clipboard'}}") span.copied-tooltip {{_ 'copied'}} textarea.js-edit-checklist-item(rows='1' autofocus dir="auto") if $eq type 'item' @@ -90,12 +91,13 @@ template(name="editChecklistItemForm") = checklist.title .edit-controls.clearfix button.primary.confirm.js-submit-edit-checklist-item-form(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form(title="{{_ 'close-edit-checklist-item'}}") + a.js-close-inlined-form(title="{{_ 'close-edit-checklist-item'}}") + | ❌ span(title=createdAt) {{ moment createdAt }} if canModifyCard a.js-delete-checklist-item {{_ "delete"}}... a.js-convert-checklist-item-to-card - i.fa.fa-copy + | 📋 | {{_ 'convertChecklistItemToCardPopup-title'}} template(name="checklistItems") @@ -105,7 +107,7 @@ template(name="checklistItems") +addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=true position="top") else a.add-checklist-item.js-open-inlined-form(title="{{_ 'add-checklist-item'}}") - i.fa.fa-plus + | ➕ .checklist-items.js-checklist-items each item in checklist.items +inlinedForm(classNames="js-edit-checklist-item" item = item checklist = checklist) @@ -117,7 +119,7 @@ template(name="checklistItems") +addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=true) else a.add-checklist-item.js-open-inlined-form(title="{{_ 'add-checklist-item'}}") - i.fa.fa-plus + | ➕ template(name='checklistItemDetail') .js-checklist-item.checklist-item(class="{{#if item.isFinished }}is-checked{{#if checklist.hideCheckedChecklistItems}} invisible{{/if}}{{/if}}{{#if checklist.hideAllChecklistItems}} is-checked invisible{{/if}}" @@ -125,8 +127,7 @@ template(name='checklistItemDetail') if canModifyCard .check-box-container .check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}") - if isTouchScreenOrShowDesktopDragHandles - span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}") + span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}") .item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}") +viewer = item.title @@ -140,16 +141,16 @@ template(name="checklistActionsPopup") ul.pop-over-list li a.js-delete-checklist.delete-checklist - i.fa.fa-trash + | 🗑️ | {{_ "delete"}} ... a.js-move-checklist.move-checklist - i.fa.fa-arrow-right + | ➡️ | {{_ "moveChecklist"}} ... a.js-copy-checklist.copy-checklist - i.fa.fa-copy + | 📋 | {{_ "copyChecklist"}} ... a.js-hide-checked-checklist-items - i.fa.fa-eye-slash + | 🙈 | {{_ "hideCheckedChecklistItems"}} ... .material-toggle-switch(title="{{_ 'hide-checked-items'}}") if checklist.hideCheckedChecklistItems @@ -158,7 +159,7 @@ template(name="checklistActionsPopup") input.toggle-switch(type="checkbox" id="toggleHideCheckedChecklistItems_{{checklist._id}}") label.toggle-label(for="toggleHideCheckedChecklistItems_{{checklist._id}}") a.js-hide-all-checklist-items - i.fa.fa-ban + | 🚫 | {{_ "hideAllChecklistItems"}} ... .material-toggle-switch(title="{{_ 'hideAllChecklistItems'}}") if checklist.hideAllChecklistItems diff --git a/client/components/cards/labels.css b/client/components/cards/labels.css index 45d886191..f4738a879 100644 --- a/client/components/cards/labels.css +++ b/client/components/cards/labels.css @@ -38,6 +38,7 @@ .palette-colors { display: flex; flex-wrap: wrap; + justify-content: flex-start; /* left-align color chips in wider popovers */ } .palette-colors .palette-color { flex-grow: 1; diff --git a/client/components/cards/labels.jade b/client/components/cards/labels.jade index 8d12dc488..d49c939d2 100644 --- a/client/components/cards/labels.jade +++ b/client/components/cards/labels.jade @@ -6,7 +6,7 @@ template(name="formLabel") .palette-colors: each labels span.card-label.palette-color.js-palette-color(class="card-label-{{color}}") if(isSelected color) - i.fa.fa-check + | ✅ template(name="createLabelPopup") form.create-label @@ -28,7 +28,8 @@ template(name="cardLabelsPopup") ul.edit-labels-pop-over each board.labels li.js-card-label-item - a.card-label-edit-button.fa.fa-pencil.js-edit-label + a.card-label-edit-button.js-edit-label + | ✏️ if isTouchScreenOrShowDesktopDragHandles span.fa.label-handle(class="fa-arrows" title="{{_ 'dragLabel'}}") span.card-label.card-label-selectable.js-select-label.card-label-wrapper(class="card-label-{{color}}" @@ -36,5 +37,5 @@ template(name="cardLabelsPopup") +viewer = name if(isLabelSelected ../_id) - i.card-label-selectable-icon.fa.fa-check + | ✅ a.quiet-button.full.js-add-label {{_ 'label-create'}} diff --git a/client/components/cards/labels.js b/client/components/cards/labels.js index e09598189..2962cae77 100644 --- a/client/components/cards/labels.js +++ b/client/components/cards/labels.js @@ -125,8 +125,19 @@ Template.createLabelPopup.events({ .$('#labelName') .val() .trim(); - const color = Blaze.getData(templateInstance.find('.fa-check')).color; - board.addLabel(name, color); + + // Find the selected color by looking for the palette color that contains the checkmark + let selectedColor = null; + templateInstance.$('.js-palette-color').each(function() { + if ($(this).text().includes('✅')) { + selectedColor = Blaze.getData(this).color; + return false; // break out of loop + } + }); + + if (selectedColor) { + board.addLabel(name, selectedColor); + } Popup.back(); }, }); @@ -144,8 +155,19 @@ Template.editLabelPopup.events({ .$('#labelName') .val() .trim(); - const color = Blaze.getData(templateInstance.find('.fa-check')).color; - board.editLabel(this._id, name, color); + + // Find the selected color by looking for the palette color that contains the checkmark + let selectedColor = null; + templateInstance.$('.js-palette-color').each(function() { + if ($(this).text().includes('✅')) { + selectedColor = Blaze.getData(this).color; + return false; // break out of loop + } + }); + + if (selectedColor) { + board.editLabel(this._id, name, selectedColor); + } Popup.back(); }, }); diff --git a/client/components/cards/minicard.css b/client/components/cards/minicard.css index 11fe181ad..8e6158826 100644 --- a/client/components/cards/minicard.css +++ b/client/components/cards/minicard.css @@ -99,8 +99,8 @@ float: none; } .minicard .minicard-labels .minicard-label { - width: 1.5vw; - height: 1.5vw; + width: clamp(12px, 1.5vw, 16px); + height: clamp(12px, 1.5vw, 16px); border-radius: 0.3vw; margin-right: 0.4vw; margin-bottom: 0.4vh; @@ -130,8 +130,8 @@ margin-right: 0.5vw; } .minicard .handle { - width: 2.5vw; - height: 2.5vw; + width: clamp(20px, 2.5vw, 28px); + height: clamp(20px, 2.5vw, 28px); position: absolute; right: 0.7vw; top: 0.7vh; @@ -168,6 +168,148 @@ .minicard .date { margin-right: 0.4vw; } + +/* Unicode icons for minicard dates - matching cardDate.css */ +.minicard .card-date.end-date time::before { + content: "🏁"; /* Finish flag - represents end/completion */ +} +.minicard .card-date.due-date time::before { + content: "⏰"; /* Alarm clock - represents due/deadline */ +} +.minicard .card-date.start-date time::before { + content: "🚀"; /* Rocket - represents start/launch */ +} +.minicard .card-date.received-date time::before { + content: "📥"; /* Inbox tray - represents received/incoming */ +} + +.minicard .card-date time::before { + font-size: inherit; + margin-right: 0.3em; + display: inline-block; +} + +/* Date type specific colors for minicards - matching cardDate.css */ +.minicard .card-date.received-date { + background-color: #dbdbdb; /* Grey for received - same as base card-date */ +} + +.minicard .card-date.received-date:hover, +.minicard .card-date.received-date.is-active { + background-color: #b3b3b3; +} + +.minicard .card-date.start-date { + background-color: #90ee90; /* Light green for start */ + color: #000; /* Black text for start */ +} + +.minicard .card-date.start-date:hover, +.minicard .card-date.start-date.is-active { + background-color: #7dd87d; +} + +.minicard .card-date.due-date { + background-color: #ffd700; /* Yellow for due */ + color: #000; /* Black text for due */ +} + +.minicard .card-date.due-date:hover, +.minicard .card-date.due-date.is-active { + background-color: #e6c200; +} + +.minicard .card-date.end-date { + background-color: #ffb3b3; /* Light red for end */ + color: #000; /* Black text for end */ +} + +.minicard .card-date.end-date:hover, +.minicard .card-date.end-date.is-active { + background-color: #ff9999; +} + +/* Date status colors for minicards - matching cardDate.css */ +.minicard .card-date.overdue { + background-color: #ff4444 !important; /* Red for overdue */ + color: #fff !important; +} +.minicard .card-date.overdue:hover, +.minicard .card-date.overdue.is-active { + background-color: #cc3333 !important; +} + +.minicard .card-date.due-soon { + background-color: #ffaa00 !important; /* Amber for due soon */ + color: #000 !important; +} +.minicard .card-date.due-soon:hover, +.minicard .card-date.due-soon.is-active { + background-color: #e69900 !important; +} + +.minicard .card-date.not-due { + /* No special background - uses default date type colors */ +} + +.minicard .card-date.current { + background-color: #5ba639 !important; /* Green for current/active */ + color: #fff !important; +} +.minicard .card-date.current:hover, +.minicard .card-date.current.is-active { + background-color: #46802c !important; +} + +.minicard .card-date.completed { + background-color: #90ee90 !important; /* Light green for completed */ + color: #000 !important; +} +.minicard .card-date.completed:hover, +.minicard .card-date.completed.is-active { + background-color: #7dd87d !important; +} + +.minicard .card-date.completed-early { + background-color: #4caf50 !important; /* Green for completed early */ + color: #fff !important; +} +.minicard .card-date.completed-early:hover, +.minicard .card-date.completed-early.is-active { + background-color: #45a049 !important; +} + +.minicard .card-date.completed-late { + background-color: #ff9800 !important; /* Orange for completed late */ + color: #fff !important; +} +.minicard .card-date.completed-late:hover, +.minicard .card-date.completed-late.is-active { + background-color: #f57c00 !important; +} + +.minicard .card-date.completed-on-time { + background-color: #2196f3 !important; /* Blue for completed on time */ + color: #fff !important; +} +.minicard .card-date.completed-on-time:hover, +.minicard .card-date.completed-on-time.is-active { + background-color: #1976d2 !important; +} + +/* Font Awesome icons in minicard dates */ +.minicard .card-date i.fa { + margin-right: 0.3vw; + font-size: 0.9em; + vertical-align: middle; +} + +/* Font Awesome icons in minicard spent time */ +.minicard .card-time i.fa { + margin-right: 0.3vw; + font-size: 0.9em; + vertical-align: middle; +} .minicard .badges { float: left; margin-top: 1vh; @@ -220,8 +362,8 @@ .minicard .minicard-creator .member { float: right; border-radius: 50%; - height: 3.5vw; - width: 3.5vw; + height: clamp(24px, 3.5vw, 32px); + width: clamp(24px, 3.5vw, 32px); margin-bottom: 0.5vh; } .minicard .minicard-members .assignee, @@ -229,8 +371,8 @@ .minicard .minicard-creator .assignee { float: right; border-radius: 50%; - height: 3.5vw; - width: 3.5vw; + height: clamp(24px, 3.5vw, 32px); + width: clamp(24px, 3.5vw, 32px); } .minicard .minicard-members + .badges, .minicard .minicard-assignees + .badges, diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 7a53192ce..b36af1ceb 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -4,19 +4,14 @@ template(name="minicard") class="{{#if isLinkedBoard}}linked-board{{/if}}" class="{{#if colorClass}}minicard-{{colorClass}}{{/if}}") if canModifyCard - if isTouchScreenOrShowDesktopDragHandles - a.fa.fa-navicon.minicard-details-menu-with-handle.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") - .handle - .fa.fa-arrows - else - a.fa.fa-navicon.minicard-details-menu.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") + a.minicard-details-menu-with-handle.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") ☰ + if canMoveCard + .handle + | ↕️ .dates if getReceived - unless getStart - unless getDue - unless getEnd - .date - +minicardReceivedDate + .date + +minicardReceivedDate if getStart .date +minicardStartDate @@ -36,7 +31,7 @@ template(name="minicard") if hasActiveUploads .minicard-upload-progress .upload-progress-header - i.fa.fa-upload + | 📤 span {{_ 'uploading-files'}} ({{uploadCount}}) each uploads .upload-progress-item(class="{{#if $eq status 'error'}}upload-error{{/if}}") @@ -45,11 +40,11 @@ template(name="minicard") .upload-progress-fill(style="width: {{progress}}%") if $eq status 'error' .upload-progress-error - i.fa.fa-exclamation-triangle + | ⚠️ span {{_ 'upload-failed'}} else if $eq status 'completed' .upload-progress-success - i.fa.fa-check + | ✅ span {{_ 'upload-completed'}} .minicard-title @@ -61,12 +56,12 @@ template(name="minicard") | {{ parentCardName }} if isLinkedBoard a.js-linked-link - span.linked-icon.fa.fa-folder + span.linked-icon | 📁 else if isLinkedCard a.js-linked-link - span.linked-icon.fa.fa-id-card + span.linked-icon | 🃏 if getArchived - span.linked-icon.linked-archived.fa.fa-archive + span.linked-icon.linked-archived | 📦 +viewer if currentBoard.allowsCardNumber span.card-number @@ -147,7 +142,7 @@ template(name="minicard") if canModifyCard if comments.length .badge(title="{{_ 'card-comments-title' comments.length }}") - span.badge-icon.fa.fa-comment-o.badge-comment.badge-text + span.badge-icon.badge-comment.badge-text 💬 = ' ' = comments.length //span.badge-comment.badge-text @@ -155,36 +150,36 @@ template(name="minicard") if getDescription unless currentBoard.allowsDescriptionTextOnMinicard .badge.badge-state-image-only(title=getDescription) - span.badge-icon.fa.fa-align-left + span.badge-icon 📝 if getVoteQuestion .badge.badge-state-image-only(title=getVoteQuestion) - span.badge-icon.fa.fa-thumbs-up(class="{{#if voteState}}text-green{{/if}}") + span.badge-icon(class="{{#if voteState}}text-green{{/if}}") 👍 span.badge-text {{ voteCountPositive }} - span.badge-icon.fa.fa-thumbs-down(class="{{#if $eq voteState false}}text-red{{/if}}") + span.badge-icon(class="{{#if $eq voteState false}}text-red{{/if}}") 👎 span.badge-text {{ voteCountNegative }} if getPokerQuestion .badge.badge-state-image-only(title=getPokerQuestion) - span.badge-icon.fa.fa-check(class="{{#if pokerState}}text-green{{/if}}") + span.badge-icon(class="{{#if pokerState}}text-green{{/if}}") ✅ if expiredPoker span.badge-text {{ getPokerEstimation }} if attachments.length if currentBoard.allowsBadgeAttachmentOnMinicard .badge - span.badge-icon.fa.fa-paperclip + span.badge-icon 📎 span.badge-text= attachments.length if checklists.length .badge(class="{{#if checklistFinished}}is-finished{{/if}}") - span.badge-icon.fa.fa-check-square-o + span.badge-icon ☑️ span.badge-text.check-list-text {{checklistFinishedCount}}/{{checklistItemCount}} if allSubtasks.count .badge - span.badge-icon.fa.fa-sitemap + span.badge-icon 🌐 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 if currentBoard.allowsCardSortingByNumberOnMinicard .badge - span.badge-icon.fa.fa-sort + span.badge-icon 🔢 span.badge-text.check-list-sort {{ sort }} if currentBoard.allowsDescriptionTextOnMinicard if getDescription @@ -193,7 +188,7 @@ template(name="minicard") | {{ getDescription }} if shouldShowListOnMinicard .minicard-list-name - i.fa.fa-list + | 📋 | {{ listName }} if $eq 'subtext-with-full-path' currentBoard.presentParentTask .parent-subtext @@ -212,50 +207,50 @@ template(name="minicardDetailsActionsPopup") if canModifyCard li a.js-move-card - i.fa.fa-arrow-right + | ➡️ | {{_ 'moveCardPopup-title'}} li a.js-copy-card - i.fa.fa-copy + | 📋 | {{_ 'copyCardPopup-title'}} hr li a.js-archive - i.fa.fa-arrow-right - i.fa.fa-archive + | ➡️ + | 📦 | {{_ 'archive-card'}} hr 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 li a.js-add-labels - i.fa.fa-tags + | 🏷️ | {{_ 'card-edit-labels'}} li a.js-due-date - i.fa.fa-sign-in + | 📥 | {{_ 'editCardDueDatePopup-title'}} li a.js-set-card-color - i.fa.fa-paint-brush + | 🎨 | {{_ 'setCardColorPopup-title'}} li a.js-link - i.fa.fa-link + | 🔗 | {{_ 'link-card'}} li a.js-toggle-watch-card if isWatching - i.fa.fa-eye + | 👁️ | {{_ 'unwatch'}} else - i.fa.fa-eye-slash + | 👁️-slash | {{_ 'watch'}} diff --git a/client/components/cards/minicard.js b/client/components/cards/minicard.js index 54898e4b5..91ebddc8c 100644 --- a/client/components/cards/minicard.js +++ b/client/components/cards/minicard.js @@ -111,55 +111,58 @@ BlazeComponent.extendComponent({ 'click .js-open-minicard-details-menu': Popup.open('minicardDetailsActions'), // Drag and drop file upload handlers 'dragover .minicard'(event) { - event.preventDefault(); - event.stopPropagation(); + // Only prevent default for file drags to avoid interfering with sortable + const dataTransfer = event.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + event.stopPropagation(); + } }, 'dragenter .minicard'(event) { - event.preventDefault(); - event.stopPropagation(); - const card = this.data(); - const board = card.board(); - // Only allow drag-and-drop if user can modify card and board allows attachments - if (card.canModifyCard() && board && board.allowsAttachments) { - // Check if the drag contains files - const dataTransfer = event.originalEvent.dataTransfer; - if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + const dataTransfer = event.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + event.stopPropagation(); + const card = this.data(); + const board = card.board(); + // Only allow drag-and-drop if user can modify card and board allows attachments + if (Utils.canModifyCard() && board && board.allowsAttachments) { $(event.currentTarget).addClass('is-dragging-over'); } } }, 'dragleave .minicard'(event) { - event.preventDefault(); - event.stopPropagation(); - $(event.currentTarget).removeClass('is-dragging-over'); + const dataTransfer = event.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + event.stopPropagation(); + $(event.currentTarget).removeClass('is-dragging-over'); + } }, 'drop .minicard'(event) { - event.preventDefault(); - event.stopPropagation(); - $(event.currentTarget).removeClass('is-dragging-over'); - - const card = this.data(); - const board = card.board(); - - // Check permissions - if (!card.canModifyCard() || !board || !board.allowsAttachments) { - return; - } - - // Check if this is a file drop (not a card reorder) const dataTransfer = event.originalEvent.dataTransfer; - if (!dataTransfer || !dataTransfer.files || dataTransfer.files.length === 0) { - return; - } + if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) { + event.preventDefault(); + event.stopPropagation(); + $(event.currentTarget).removeClass('is-dragging-over'); - // Check if the drop contains files (not just text/HTML) - if (!dataTransfer.types.includes('Files')) { - return; - } + const card = this.data(); + const board = card.board(); - const files = dataTransfer.files; - if (files && files.length > 0) { - handleFileUpload(card, files); + // Check permissions + if (!Utils.canModifyCard() || !board || !board.allowsAttachments) { + return; + } + + // Check if this is a file drop (not a card reorder) + if (!dataTransfer.files || dataTransfer.files.length === 0) { + return; + } + + const files = dataTransfer.files; + if (files && files.length > 0) { + handleFileUpload(card, files); + } } }, } @@ -206,7 +209,9 @@ Template.minicard.helpers({ // Show list name if either: // 1. Board-wide setting is enabled, OR // 2. This specific card has the setting enabled - return this.currentBoard.allowsShowListsOnMinicard || this.showListOnMinicard; + const currentBoard = this.currentBoard; + if (!currentBoard) return false; + return currentBoard.allowsShowListsOnMinicard || this.showListOnMinicard; } }); diff --git a/client/components/cards/resultCard.jade b/client/components/cards/resultCard.jade index ae6e90722..f2bd16657 100644 --- a/client/components/cards/resultCard.jade +++ b/client/components/cards/resultCard.jade @@ -13,7 +13,7 @@ template(name="resultCard") .broken-cards-null | NULL if getBoard.archived - i.fa.fa-archive + | 📦 li.result-card-context.result-card-context-separator = ' ' | {{_ 'context-separator'}} @@ -27,7 +27,7 @@ template(name="resultCard") .broken-cards-null | NULL if getSwimlane.archived - i.fa.fa-archive + | 📦 li.result-card-context.result-card-context-separator = ' ' | {{_ 'context-separator'}} @@ -41,4 +41,4 @@ template(name="resultCard") .broken-cards-null | NULL if getList.archived - i.fa.fa-archive + | 📦 diff --git a/client/components/cards/subtasks.jade b/client/components/cards/subtasks.jade index 7e8f58d04..ceb860e6e 100644 --- a/client/components/cards/subtasks.jade +++ b/client/components/cards/subtasks.jade @@ -1,6 +1,6 @@ template(name="subtasks") h3.card-details-item-title - i.fa.fa-sitemap + | 🌐 | {{_ 'subtasks'}} if currentUser.isBoardAdmin if toggleDeleteDialog.get @@ -16,7 +16,7 @@ template(name="subtasks") +addSubtaskItemForm else a.js-open-inlined-form(title="{{_ 'add-subtask'}}") - i.fa.fa-plus + | ➕ template(name="subtaskDetail") .js-subtasks.subtask @@ -26,7 +26,7 @@ template(name="subtaskDetail") .subtask-title span if canModifyCard - a.fa.fa-navicon.subtask-details-menu.js-open-subtask-details-menu(title="{{_ 'subtaskActionsPopup-title'}}") + a.subtask-details-menu.js-open-subtask-details-menu(title="{{_ 'subtaskActionsPopup-title'}}") if canModifyCard h2.title.js-open-inlined-form.is-editable +viewer @@ -40,7 +40,7 @@ template(name="addSubtaskItemForm") textarea.js-add-subtask-item(rows='1' autofocus dir="auto") .edit-controls.clearfix button.primary.confirm.js-submit-add-subtask-item-form(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form template(name="editSubtaskItemForm") textarea.js-edit-subtask-item(rows='1' autofocus dir="auto") @@ -50,7 +50,7 @@ template(name="editSubtaskItemForm") = subtask.title .edit-controls.clearfix button.primary.confirm.js-submit-edit-subtask-item-form(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form span(title=createdAt) {{ moment createdAt }} if canModifyCard if currentUser.isBoardAdmin @@ -68,7 +68,7 @@ template(name="subtasksItems") +addSubtaskItemForm else a.add-subtask-item.js-open-inlined-form - i.fa.fa-plus + | ➕ | {{_ 'add-subtask-item'}}... template(name='subtaskItemDetail') @@ -92,10 +92,10 @@ template(name="subtaskActionsPopup") ul.pop-over-list li a.js-view-subtask(title="{{ subtask.title }}") - i.fa.fa-eye + | 👁️ | {{_ "view-it"}} if currentUser.isBoardAdmin a.js-delete-subtask.delete-subtask - i.fa.fa-trash + | 🗑️ | {{_ "delete"}} ... diff --git a/client/components/common/originalPosition.css b/client/components/common/originalPosition.css new file mode 100644 index 000000000..1c31c4860 --- /dev/null +++ b/client/components/common/originalPosition.css @@ -0,0 +1,123 @@ +/* Original Position Component Styles */ +.original-position-info { + margin: 5px 0; + padding: 8px; + border-radius: 4px; + font-size: 12px; + line-height: 1.4; +} + +.original-position-loading { + color: #666; + font-style: italic; +} + +.original-position-loading i { + margin-right: 5px; +} + +.original-position-details { + background-color: #f8f9fa; + border: 1px solid #e9ecef; + border-radius: 3px; + padding: 6px 8px; +} + +.original-position-moved { + color: #856404; + background-color: #fff3cd; + border: 1px solid #ffeaa7; + border-radius: 3px; + padding: 4px 6px; + margin-bottom: 4px; +} + +.original-position-moved i { + color: #f39c12; + margin-right: 5px; +} + +.original-position-unchanged { + color: #155724; + background-color: #d4edda; + border: 1px solid #c3e6cb; + border-radius: 3px; + padding: 4px 6px; + margin-bottom: 4px; +} + +.original-position-unchanged i { + color: #28a745; + margin-right: 5px; +} + +.original-position-text { + font-weight: 500; +} + +.original-title { + color: #6c757d; + font-size: 11px; + margin-top: 4px; + padding-top: 4px; + border-top: 1px solid #e9ecef; +} + +.original-title strong { + color: #495057; +} + +/* Integration with existing Wekan styles */ +.swimlane .original-position-info, +.list .original-position-info, +.card .original-position-info { + margin: 2px 0; + padding: 4px 6px; +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .original-position-info { + font-size: 11px; + padding: 6px; + } + + .original-position-details { + padding: 4px 6px; + } + + .original-position-moved, + .original-position-unchanged { + padding: 3px 5px; + } +} + +/* Dark theme support */ +@media (prefers-color-scheme: dark) { + .original-position-details { + background-color: #2d3748; + border-color: #4a5568; + color: #e2e8f0; + } + + .original-position-moved { + background-color: #744210; + border-color: #b7791f; + color: #fbd38d; + } + + .original-position-unchanged { + background-color: #22543d; + border-color: #38a169; + color: #9ae6b4; + } + + .original-title { + color: #a0aec0; + border-color: #4a5568; + } + + .original-title strong { + color: #e2e8f0; + } +} diff --git a/client/components/common/originalPosition.html b/client/components/common/originalPosition.html new file mode 100644 index 000000000..3e3191e27 --- /dev/null +++ b/client/components/common/originalPosition.html @@ -0,0 +1,29 @@ + diff --git a/client/components/common/originalPosition.js b/client/components/common/originalPosition.js new file mode 100644 index 000000000..37e0a4522 --- /dev/null +++ b/client/components/common/originalPosition.js @@ -0,0 +1,98 @@ +import { BlazeComponent } from 'meteor/peerlibrary:blaze-components'; +import { ReactiveVar } from 'meteor/reactive-var'; +import { Meteor } from 'meteor/meteor'; +import { Template } from 'meteor/templating'; +import './originalPosition.html'; + +/** + * Component to display original position information for swimlanes, lists, and cards + */ +class OriginalPositionComponent extends BlazeComponent { + onCreated() { + super.onCreated(); + this.originalPosition = new ReactiveVar(null); + this.isLoading = new ReactiveVar(false); + this.hasMoved = new ReactiveVar(false); + + this.autorun(() => { + const data = this.data(); + if (data && data.entityId && data.entityType) { + this.loadOriginalPosition(data.entityId, data.entityType); + } + }); + } + + loadOriginalPosition(entityId, entityType) { + this.isLoading.set(true); + + const methodName = `positionHistory.get${entityType.charAt(0).toUpperCase() + entityType.slice(1)}OriginalPosition`; + + Meteor.call(methodName, entityId, (error, result) => { + this.isLoading.set(false); + if (error) { + console.error('Error loading original position:', error); + this.originalPosition.set(null); + } else { + this.originalPosition.set(result); + + // Check if the entity has moved + const movedMethodName = `positionHistory.has${entityType.charAt(0).toUpperCase() + entityType.slice(1)}Moved`; + Meteor.call(movedMethodName, entityId, (movedError, movedResult) => { + if (!movedError) { + this.hasMoved.set(movedResult); + } + }); + } + }); + } + + getOriginalPosition() { + return this.originalPosition.get(); + } + + isLoading() { + return this.isLoading.get(); + } + + hasMovedFromOriginal() { + return this.hasMoved.get(); + } + + getOriginalPositionDescription() { + const position = this.getOriginalPosition(); + if (!position) return 'No original position data'; + + if (position.originalPosition) { + const entityType = this.data().entityType; + let description = `Original position: ${position.originalPosition.sort || 0}`; + + if (entityType === 'list' && position.originalSwimlaneId) { + description += ` in swimlane ${position.originalSwimlaneId}`; + } else if (entityType === 'card') { + if (position.originalSwimlaneId) { + description += ` in swimlane ${position.originalSwimlaneId}`; + } + if (position.originalListId) { + description += ` in list ${position.originalListId}`; + } + } + + return description; + } + + return 'No original position data'; + } + + getOriginalTitle() { + const position = this.getOriginalPosition(); + return position ? position.originalTitle : ''; + } + + showOriginalPosition() { + return this.getOriginalPosition() !== null; + } +} + +OriginalPositionComponent.register('originalPosition'); + +export default OriginalPositionComponent; diff --git a/client/components/forms/datepicker.jade b/client/components/forms/datepicker.jade index 96f63bc49..c8fb0524a 100644 --- a/client/components/forms/datepicker.jade +++ b/client/components/forms/datepicker.jade @@ -4,11 +4,10 @@ template(name="datepicker") .fields .left label(for="date") {{_ 'date'}} - input.js-date-field#date(type="text" name="date" value=showDate placeholder=dateFormat autofocus) + input.js-date-field#date(type="date" name="date" value=showDate autofocus) .right label(for="time") {{_ 'time'}} - input.js-time-field#time(type="text" name="time" value=showTime placeholder=timeFormat) - .js-datepicker + input.js-time-field#time(type="time" name="time" value=showTime) if error.get .warning {{_ error.get}} button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}} diff --git a/client/components/import/import.jade b/client/components/import/import.jade index 7b55dadbd..ed42fe44b 100644 --- a/client/components/import/import.jade +++ b/client/components/import/import.jade @@ -56,17 +56,17 @@ template(name="importMapMembersAddPopup") p | {{_ 'import-user-select'}} .js-map-member - +EasySearch.Input(index=searchIndex) + input.js-search-member-input(type="text" placeholder="{{_ 'search-users'}}") ul.pop-over-list - +EasySearch.Each(index=searchIndex) + each searchResults li.item.js-member-item - a.name.js-select-import(title="{{profile.fullname}} ({{username}})" data-id="{{__originalId}}") - +userAvatar(userId=__originalId) + a.name.js-select-import(title="{{profile.fullname}} ({{username}})" data-id="{{_id}}") + +userAvatar(userId=_id) span.full-name = profile.fullname | ({{username}}) - +EasySearch.IfSearching(index=searchIndex) + if searching.get +spinner - +EasySearch.IfNoResults(index=searchIndex) + if noResults.get .manage-member-section p.quiet {{_ 'no-results'}} diff --git a/client/components/import/import.js b/client/components/import/import.js index 4d4ba7fa7..757b55e41 100644 --- a/client/components/import/import.js +++ b/client/components/import/import.js @@ -311,6 +311,73 @@ BlazeComponent.extendComponent({ }, }).register('importMapMembersAddPopup'); +// Global reactive variables for import member popup +const importMemberPopupState = { + searching: new ReactiveVar(false), + searchResults: new ReactiveVar([]), + noResults: new ReactiveVar(false), + searchTimeout: null +}; + +BlazeComponent.extendComponent({ + onCreated() { + // Use global state + this.searching = importMemberPopupState.searching; + this.searchResults = importMemberPopupState.searchResults; + this.noResults = importMemberPopupState.noResults; + this.searchTimeout = importMemberPopupState.searchTimeout; + }, + + onRendered() { + this.find('.js-search-member-input').focus(); + }, + + performSearch(query) { + if (!query || query.length < 2) { + this.searchResults.set([]); + this.noResults.set(false); + return; + } + + this.searching.set(true); + this.noResults.set(false); + + const results = UserSearchIndex.search(query, { limit: 20 }).fetch(); + this.searchResults.set(results); + this.searching.set(false); + + if (results.length === 0) { + this.noResults.set(true); + } + }, + + events() { + return [ + { + 'keyup .js-search-member-input'(event) { + const query = event.target.value.trim(); + + if (this.searchTimeout) { + clearTimeout(this.searchTimeout); + } + + this.searchTimeout = setTimeout(() => { + this.performSearch(query); + }, 300); + }, + }, + ]; + }, +}).register('importMapMembersAddPopupSearch'); + Template.importMapMembersAddPopup.helpers({ - searchIndex: () => UserSearchIndex, + searchResults() { + return importMemberPopupState.searchResults.get(); + }, + searching() { + return importMemberPopupState.searching; + }, + noResults() { + return importMemberPopupState.noResults; + } }) diff --git a/client/components/lists/list.css b/client/components/lists/list.css index c81551aaf..77e78de29 100644 --- a/client/components/lists/list.css +++ b/client/components/lists/list.css @@ -8,6 +8,228 @@ padding: 0; float: left; } + +/* List resize handle */ +.list-resize-handle { + position: absolute; + top: 0; + right: -3px; + width: 6px; + height: 100%; + cursor: col-resize; + z-index: 10; + background: transparent; + transition: background-color 0.2s ease; + border-radius: 2px; + /* Ensure the handle is clickable */ + pointer-events: auto; +} + +.list-resize-handle:hover { + background: rgba(0, 123, 255, 0.4); + box-shadow: 0 0 4px rgba(0, 123, 255, 0.3); +} + +.list-resize-handle:active { + background: rgba(0, 123, 255, 0.6); + box-shadow: 0 0 6px rgba(0, 123, 255, 0.4); +} + +/* Show resize handle only on hover */ +.list:hover .list-resize-handle { + background: rgba(0, 0, 0, 0.1); +} + +.list:hover .list-resize-handle:hover { + background: rgba(0, 123, 255, 0.4); + box-shadow: 0 0 4px rgba(0, 123, 255, 0.3); +} + +/* Add a subtle indicator line */ +.list-resize-handle::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 2px; + height: 20px; + background: rgba(0, 0, 0, 0.2); + border-radius: 1px; + opacity: 0; + transition: opacity 0.2s ease; +} + +.list-resize-handle:hover::before { + opacity: 1; +} + +/* Disable resize handle for collapsed lists and mobile view */ +.list.list-collapsed .list-resize-handle, +.list.mobile-view .list-resize-handle { + display: none; +} + +/* Disable resize handle for auto-width lists */ +.list.list-auto-width .list-resize-handle { + display: none; +} + +/* Visual feedback during resize */ +.list.list-resizing { + transition: none !important; + box-shadow: 0 0 10px rgba(0, 123, 255, 0.3); + /* Ensure the list maintains its new width during resize */ + flex: none !important; + flex-basis: auto !important; + flex-grow: 0 !important; + flex-shrink: 0 !important; + /* Override any conflicting layout properties */ + float: left !important; + display: block !important; + position: relative !important; + /* Force width to be respected */ + width: var(--list-width, auto) !important; + min-width: var(--list-width, auto) !important; + max-width: var(--list-width, auto) !important; + /* Ensure the width is applied immediately */ + overflow: visible !important; +} + +body.list-resizing-active { + cursor: col-resize !important; +} + +body.list-resizing-active * { + cursor: col-resize !important; +} + +/* Ensure swimlane container doesn't interfere with list resizing */ +.swimlane .list.list-resizing { + /* Override any swimlane flex properties */ + flex: none !important; + flex-basis: auto !important; + flex-grow: 0 !important; + flex-shrink: 0 !important; + /* Ensure width is respected */ + width: var(--list-width, auto) !important; + min-width: var(--list-width, auto) !important; + max-width: var(--list-width, auto) !important; +} + +/* More aggressive override for any container that might interfere */ +.js-swimlane .list.list-resizing, +.dragscroll .list.list-resizing, +[id^="swimlane-"] .list.list-resizing { + /* Force the width to be applied */ + width: var(--list-width, auto) !important; + min-width: var(--list-width, auto) !important; + max-width: var(--list-width, auto) !important; + flex: none !important; + flex-basis: auto !important; + flex-grow: 0 !important; + flex-shrink: 0 !important; + float: left !important; + display: block !important; +} + +/* Ensure the width persists after resize is complete */ +.js-swimlane .list[style*="--list-width"], +.dragscroll .list[style*="--list-width"], +[id^="swimlane-"] .list[style*="--list-width"] { + /* Maintain the width after resize */ + width: var(--list-width, auto) !important; + min-width: var(--list-width, auto) !important; + max-width: var(--list-width, auto) !important; + flex: none !important; + flex-basis: auto !important; + flex-grow: 0 !important; + flex-shrink: 0 !important; + float: left !important; + display: block !important; +} + +/* Ensure consistent header height for all lists */ +.list-header { + /* Maintain consistent height and padding for all lists */ + min-height: 2.5vh !important; + height: auto !important; + padding: 2.5vh 1.5vw 0.5vh !important; + /* Make sure the background covers the full height */ + background-color: #e4e4e4 !important; + border-bottom: 0.8vh solid #e4e4e4 !important; + /* Use original display for consistent button positioning */ + display: block !important; + position: relative !important; + /* Prevent vertical expansion but allow normal height */ + overflow: hidden !important; +} + +/* Ensure title text doesn't cause height changes for all lists */ +.list-header .list-header-name { + /* Prevent text wrapping to maintain consistent height */ + white-space: nowrap !important; + /* Truncate text with ellipsis if too long */ + text-overflow: ellipsis !important; + /* Ensure proper line height */ + line-height: 1.2 !important; + /* Ensure it doesn't overflow */ + overflow: hidden !important; + /* Add margin to prevent overlap with buttons */ + margin-right: 120px !important; +} + +/* Position drag handle at top-right corner for ALL lists */ +.list-header .list-header-handle { + /* Position at top-right corner, aligned with title text top */ + position: absolute !important; + top: 2.5vh !important; + right: 1.5vw !important; + /* Ensure it's above other elements */ + z-index: 15 !important; + /* Remove margin since it's absolutely positioned */ + margin-right: 0 !important; + /* Ensure proper display */ + display: inline-block !important; + /* Ensure it's clickable and shows proper cursor */ + cursor: move !important; + pointer-events: auto !important; + /* Add some padding for better clickability */ + padding: 4px !important; +} + +/* Ensure buttons maintain original positioning */ +.js-swimlane .list[style*="--list-width"] .list-header .list-header-plus-top, +.js-swimlane .list[style*="--list-width"] .list-header .js-collapse, +.js-swimlane .list[style*="--list-width"] .list-header .js-open-list-menu, +.dragscroll .list[style*="--list-width"] .list-header .list-header-plus-top, +.dragscroll .list[style*="--list-width"] .list-header .js-collapse, +.dragscroll .list[style*="--list-width"] .list-header .js-open-list-menu, +[id^="swimlane-"] .list[style*="--list-width"] .list-header .list-header-plus-top, +[id^="swimlane-"] .list[style*="--list-width"] .list-header .js-collapse, +[id^="swimlane-"] .list[style*="--list-width"] .list-header .js-open-list-menu { + /* Use original positioning to maintain layout */ + position: relative !important; + /* Maintain original spacing */ + margin-right: 15px !important; + /* Ensure proper display */ + display: inline-block !important; +} + +/* Ensure watch icon and card count maintain original positioning */ +.js-swimlane .list[style*="--list-width"] .list-header .list-header-watch-icon, +.dragscroll .list[style*="--list-width"] .list-header .list-header-watch-icon, +[id^="swimlane-"] .list[style*="--list-width"] .list-header .list-header-watch-icon, +.js-swimlane .list[style*="--list-width"] .list-header .cardCount, +.dragscroll .list[style*="--list-width"] .list-header .cardCount, +[id^="swimlane-"] .list[style*="--list-width"] .list-header .cardCount { + /* Use original positioning to maintain layout */ + position: relative !important; + /* Maintain original spacing */ + margin-right: 15px !important; + /* Ensure proper display */ + display: inline-block !important; +} [id^="swimlane-"] .list:first-child { min-width: 2.5vw; } @@ -37,7 +259,70 @@ } .list.list-collapsed { flex: none; + min-width: 60px; + max-width: 80px; + width: 60px; + min-height: 60vh; + height: 60vh; + overflow: visible; + position: relative; } +.list.list-collapsed .list-header { + padding: 1vh 1.5vw 0.5vh; + min-height: 2.5vh !important; + height: auto !important; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + position: relative; + overflow: visible !important; + width: 100%; + max-width: 60px; + margin: 0 auto; +} +.list.list-collapsed .list-header .js-collapse { + margin: 0 auto 20px auto; + z-index: 10; + padding: 8px 12px; + font-size: 12px; + white-space: nowrap; + display: block; + width: fit-content; +} +.list.list-collapsed .list-header .list-rotated { + width: auto !important; + height: auto !important; + margin: 20px 0 0 0 !important; + position: relative !important; + overflow: visible !important; +} + +.list.list-collapsed .list-header .list-rotated h2.list-header-name { + text-align: left; + overflow: visible; + white-space: nowrap; + display: block !important; + font-size: 12px; + line-height: 1.2; + color: #333; + background-color: rgba(255, 255, 255, 0.95); + border: 1px solid #ddd; + padding: 8px 4px; + border-radius: 4px; + margin: 0 auto; + width: 25vh; + height: 60vh; + position: absolute; + left: 50%; + top: 50%; + transform: translate(calc(-50% + 50px), -50%) rotate(0deg); + z-index: 10; + visibility: visible !important; + opacity: 1 !important; + pointer-events: none; +} + .list.list-composer .open-list-composer, .list .list-composer .open-list-composer { color: #8c8c8c; @@ -93,9 +378,6 @@ position: relative; text-overflow: ellipsis; white-space: nowrap; -} -.list-header .list-rotated { - } .list-header .list-header-watch-icon { padding-left: 10px; @@ -121,11 +403,152 @@ color: #a6a6a6; margin-right: 15px; } -.list-header .list-header-uncollapse-left { +.list-header .js-collapse { color: #a6a6a6; + margin-right: 15px; + display: inline-block; + vertical-align: middle; + padding: 5px 8px; + border: 1px solid #ccc; + border-radius: 4px; + background-color: #f5f5f5; + cursor: pointer; + font-size: 14px; } -.list-header .list-header-uncollapse-right { - color: #a6a6a6; +.list-header .js-collapse:hover { + background-color: #e0e0e0; + color: #333; +} +.list.list-collapsed .list-header .js-collapse { + display: inline-block !important; + visibility: visible !important; + opacity: 1 !important; +} + +/* Responsive adjustments for collapsed lists */ +@media (min-width: 768px) { + .list.list-collapsed { + min-width: 60px; + max-width: 80px; + width: 60px; + min-height: 60vh; + height: 60vh; + } + .list.list-collapsed .list-header { + max-width: 60px; + margin: 0 auto; + min-height: 2.5vh !important; + height: auto !important; + } + .list.list-collapsed .list-header .list-rotated { + width: auto !important; + height: auto !important; + margin: 20px 0 0 0 !important; + position: relative !important; + } + .list.list-collapsed .list-header .list-rotated h2.list-header-name { + width: 15vh; + font-size: 12px; + height: 30px; + line-height: 1.2; + padding: 8px 4px; + margin: 0 auto; + position: absolute; + left: 50%; + top: 50%; + transform: translate(calc(-50% + 50px), -50%) rotate(0deg); + text-align: left; + visibility: visible !important; + opacity: 1 !important; + display: block !important; + background-color: rgba(255, 255, 255, 0.95); + border: 1px solid #ddd; + color: #333; + z-index: 10; + } + .list.list-collapsed .list-header .js-collapse { + margin: 0 auto 20px auto; + } +} + +@media (min-width: 1024px) { + .list.list-collapsed { + min-height: 60vh; + height: 60vh; + } + .list.list-collapsed .list-header { + min-height: 2.5vh !important; + height: auto !important; + } + .list.list-collapsed .list-header .list-rotated { + width: auto !important; + height: auto !important; + margin: 20px 0 0 0 !important; + position: relative !important; + } + .list.list-collapsed .list-header .list-rotated h2.list-header-name { + width: 15vh; + font-size: 12px; + height: 30px; + line-height: 1.2; + padding: 8px 4px; + margin: 0 auto; + position: absolute; + left: 50%; + top: 50%; + transform: translate(calc(-50% + 50px), -50%) rotate(0deg); + text-align: left; + visibility: visible !important; + opacity: 1 !important; + display: block !important; + background-color: rgba(255, 255, 255, 0.95); + border: 1px solid #ddd; + color: #333; + z-index: 10; + } + .list.list-collapsed .list-header .js-collapse { + margin: 0 auto 20px auto; + } +} + +@media (min-width: 1200px) { + .list.list-collapsed { + min-height: 60vh; + height: 60vh; + } + .list.list-collapsed .list-header { + min-height: 2.5vh !important; + height: auto !important; + } + .list.list-collapsed .list-header .list-rotated { + width: auto !important; + height: auto !important; + margin: 20px 0 0 0 !important; + position: relative !important; + } + .list.list-collapsed .list-header .list-rotated h2.list-header-name { + width: 15vh; + font-size: 12px; + height: 30px; + line-height: 1.2; + padding: 8px 4px; + margin: 0 auto; + position: absolute; + left: 50%; + top: 50%; + transform: translate(calc(-50% + 50px), -50%) rotate(0deg); + text-align: left; + visibility: visible !important; + opacity: 1 !important; + display: block !important; + background-color: rgba(255, 255, 255, 0.95); + border: 1px solid #ddd; + color: #333; + z-index: 10; + } + .list.list-collapsed .list-header .js-collapse { + margin: 0 auto 20px auto; + } } .list-header .list-header-collapse { color: #a6a6a6; @@ -218,17 +641,22 @@ .mini-list.mobile-view { flex: 0 0 60px; height: auto; - width: 100%; - min-width: 100%; - border-left: 0px; + width: 100vw; + max-width: 100vw; + min-width: 100vw; + border-left: 0px !important; border-bottom: 1px solid #ccc; + display: block !important; } .list.mobile-view { - display: contents; + display: block !important; flex-basis: auto; - width: 100%; - min-width: 100%; - border-left: 0px; + width: 100vw; + max-width: 100vw; + min-width: 100vw; + border-left: 0px !important; + margin: 0 !important; + padding: 0 !important; } .list.mobile-view:first-child { margin-left: 0px; @@ -236,9 +664,11 @@ .list.mobile-view.ui-sortable-helper { flex: 0 0 60px; height: 60px; - width: 100%; - border-left: 0px; + width: 100vw; + max-width: 100vw; + border-left: 0px !important; border-bottom: 1px solid #ccc; + display: block !important; } .list.mobile-view.ui-sortable-helper .list-header.ui-sortable-handle { cursor: grabbing; @@ -246,14 +676,17 @@ .list.mobile-view.placeholder { flex: 0 0 60px; height: 60px; - width: 100%; - border-left: 0px; + width: 100vw; + max-width: 100vw; + border-left: 0px !important; border-bottom: 1px solid #ccc; + display: block !important; } .list.mobile-view .list-body { padding: 15px 19px; - width: 100%; - min-width: 100%; + width: 100vw; + max-width: 100vw; + min-width: 100vw; } .list.mobile-view .list-header { /*Updated padding values for mobile devices, this should fix text grouping issue*/ @@ -262,8 +695,9 @@ min-height: 30px; margin-top: 10px; align-items: center; - width: 100%; - min-width: 100%; + width: 100vw; + max-width: 100vw; + min-width: 100vw; /* Force grid layout for iPhone */ display: grid !important; grid-template-columns: 30px 1fr auto auto !important; @@ -339,21 +773,27 @@ align-items: initial; } -@media screen and (max-width: 800px) { +@media screen and (max-width: 800px), + screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) { .mini-list { flex: 0 0 60px; height: auto; - width: 100%; - min-width: 100%; - border-left: 0px; + width: 100vw; + max-width: 100vw; + min-width: 100vw; + border-left: 0px !important; border-bottom: 1px solid #ccc; + display: block !important; } .list { - display: contents; + display: block !important; flex-basis: auto; - width: 100%; - min-width: 100%; - border-left: 0px; + width: 100vw; + max-width: 100vw; + min-width: 100vw; + border-left: 0px !important; + margin: 0 !important; + padding: 0 !important; } .list:first-child { margin-left: 0px; @@ -361,9 +801,11 @@ .list.ui-sortable-helper { flex: 0 0 60px; height: 60px; - width: 100%; - border-left: 0px; + width: 100vw; + max-width: 100vw; + border-left: 0px !important; border-bottom: 1px solid #ccc; + display: block !important; } .list.ui-sortable-helper .list-header.ui-sortable-handle { cursor: grabbing; @@ -371,14 +813,17 @@ .list.placeholder { flex: 0 0 60px; height: 60px; - width: 100%; - border-left: 0px; + width: 100vw; + max-width: 100vw; + border-left: 0px !important; border-bottom: 1px solid #ccc; + display: block !important; } .list-body { padding: 15px 19px; - width: 100%; - min-width: 100%; + width: 100vw; + max-width: 100vw; + min-width: 100vw; } .list-header { /*Updated padding values for mobile devices, this should fix text grouping issue*/ @@ -387,8 +832,9 @@ min-height: 30px; margin-top: 10px; align-items: center; - width: 100%; - min-width: 100%; + width: 100vw; + max-width: 100vw; + min-width: 100vw; } .list-header .list-header-left-icon { padding: 7px; diff --git a/client/components/lists/list.jade b/client/components/lists/list.jade index 0c87fd117..eed4d67f9 100644 --- a/client/components/lists/list.jade +++ b/client/components/lists/list.jade @@ -4,6 +4,7 @@ template(name='list') class="{{#if collapsed}}list-collapsed{{/if}} {{#if autoWidth}}list-auto-width{{/if}} {{#if isMiniScreen}}mobile-view{{/if}}") +listHeader +listBody + .list-resize-handle.js-list-resize-handle.nodragscroll template(name='miniList') a.mini-list.js-select-list.js-list(id="js-list-{{_id}}" class="{{#if isMiniScreen}}mobile-view{{/if}}") diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 90c23fa52..7501886ae 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -24,6 +24,9 @@ BlazeComponent.extendComponent({ onRendered() { const boardComponent = this.parentComponent().parentComponent(); + // Initialize list resize functionality immediately + this.initializeListResize(); + const itemsSelector = '.js-minicard:not(.placeholder, .js-card-composer)'; const $cards = this.$('.js-minicards'); @@ -147,17 +150,13 @@ BlazeComponent.extendComponent({ }); this.autorun(() => { - if (Utils.isTouchScreenOrShowDesktopDragHandles()) { - $cards.sortable({ - handle: '.handle', - }); - } else { - $cards.sortable({ - handle: '.minicard', - }); - } - if ($cards.data('uiSortable') || $cards.data('sortable')) { + if (Utils.isTouchScreenOrShowDesktopDragHandles()) { + $cards.sortable('option', 'handle', '.handle'); + } else { + $cards.sortable('option', 'handle', '.minicard'); + } + $cards.sortable( 'option', 'disabled', @@ -198,20 +197,259 @@ BlazeComponent.extendComponent({ listWidth() { const user = ReactiveCache.getCurrentUser(); const list = Template.currentData(); - return user.getListWidth(list.boardId, list._id); + if (!list) return 270; // Return default width if list is not available + + if (user) { + // For logged-in users, get from user profile + return user.getListWidthFromStorage(list.boardId, list._id); + } else { + // For non-logged-in users, get from localStorage + try { + const stored = localStorage.getItem('wekan-list-widths'); + if (stored) { + const widths = JSON.parse(stored); + if (widths[list.boardId] && widths[list.boardId][list._id]) { + return widths[list.boardId][list._id]; + } + } + } catch (e) { + console.warn('Error reading list width from localStorage:', e); + } + return 270; // Return default width if not found + } }, listConstraint() { const user = ReactiveCache.getCurrentUser(); const list = Template.currentData(); - return user.getListConstraint(list.boardId, list._id); + if (!list) return 550; // Return default constraint if list is not available + + if (user) { + // For logged-in users, get from user profile + return user.getListConstraintFromStorage(list.boardId, list._id); + } else { + // For non-logged-in users, get from localStorage + try { + const stored = localStorage.getItem('wekan-list-constraints'); + if (stored) { + const constraints = JSON.parse(stored); + if (constraints[list.boardId] && constraints[list.boardId][list._id]) { + return constraints[list.boardId][list._id]; + } + } + } catch (e) { + console.warn('Error reading list constraint from localStorage:', e); + } + return 550; // Return default constraint if not found + } }, autoWidth() { const user = ReactiveCache.getCurrentUser(); const list = Template.currentData(); + if (!user) { + // For non-logged-in users, auto-width is disabled + return false; + } return user.isAutoWidth(list.boardId); }, + + initializeListResize() { + // Check if we're still in a valid template context + if (!Template.currentData()) { + console.warn('No current template data available for list resize initialization'); + return; + } + + const list = Template.currentData(); + const $list = this.$('.js-list'); + const $resizeHandle = this.$('.js-list-resize-handle'); + + // Check if elements exist + if (!$list.length || !$resizeHandle.length) { + console.warn('List or resize handle not found, retrying in 100ms'); + Meteor.setTimeout(() => { + if (!this.isDestroyed) { + this.initializeListResize(); + } + }, 100); + return; + } + + + // Only enable resize for non-collapsed, non-auto-width lists + const isAutoWidth = this.autoWidth(); + if (list.collapsed || isAutoWidth) { + $resizeHandle.hide(); + return; + } + + let isResizing = false; + let startX = 0; + let startWidth = 0; + let minWidth = 100; // Minimum width as defined in the existing code + let maxWidth = this.listConstraint() || 1000; // Use constraint as max width + let listConstraint = this.listConstraint(); // Store constraint value for use in event handlers + const component = this; // Store reference to component for use in event handlers + + const startResize = (e) => { + isResizing = true; + startX = e.pageX || e.originalEvent.touches[0].pageX; + startWidth = $list.outerWidth(); + + + // Add visual feedback + $list.addClass('list-resizing'); + $('body').addClass('list-resizing-active'); + + + // Prevent text selection during resize + $('body').css('user-select', 'none'); + + e.preventDefault(); + e.stopPropagation(); + }; + + const doResize = (e) => { + if (!isResizing) { + return; + } + + const currentX = e.pageX || e.originalEvent.touches[0].pageX; + const deltaX = currentX - startX; + const newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + deltaX)); + + // Apply the new width immediately for real-time feedback + $list[0].style.setProperty('--list-width', `${newWidth}px`); + $list[0].style.setProperty('width', `${newWidth}px`); + $list[0].style.setProperty('min-width', `${newWidth}px`); + $list[0].style.setProperty('max-width', `${newWidth}px`); + $list[0].style.setProperty('flex', 'none'); + $list[0].style.setProperty('flex-basis', 'auto'); + $list[0].style.setProperty('flex-grow', '0'); + $list[0].style.setProperty('flex-shrink', '0'); + + + e.preventDefault(); + e.stopPropagation(); + }; + + const stopResize = (e) => { + if (!isResizing) return; + + isResizing = false; + + // Calculate final width + const currentX = e.pageX || e.originalEvent.touches[0].pageX; + const deltaX = currentX - startX; + const finalWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + deltaX)); + + // Ensure the final width is applied + $list[0].style.setProperty('--list-width', `${finalWidth}px`); + $list[0].style.setProperty('width', `${finalWidth}px`); + $list[0].style.setProperty('min-width', `${finalWidth}px`); + $list[0].style.setProperty('max-width', `${finalWidth}px`); + $list[0].style.setProperty('flex', 'none'); + $list[0].style.setProperty('flex-basis', 'auto'); + $list[0].style.setProperty('flex-grow', '0'); + $list[0].style.setProperty('flex-shrink', '0'); + + // Remove visual feedback but keep the width + $list.removeClass('list-resizing'); + $('body').removeClass('list-resizing-active'); + $('body').css('user-select', ''); + + // Keep the CSS custom property for persistent width + // The CSS custom property will remain on the element to maintain the width + + // Save the new width using the existing system + const boardId = list.boardId; + const listId = list._id; + + // Use the new storage method that handles both logged-in and non-logged-in users + if (process.env.DEBUG === 'true') { + } + + const currentUser = ReactiveCache.getCurrentUser(); + if (currentUser) { + // For logged-in users, use server method + Meteor.call('applyListWidthToStorage', boardId, listId, finalWidth, listConstraint, (error, result) => { + if (error) { + console.error('Error saving list width:', error); + } else { + if (process.env.DEBUG === 'true') { + } + } + }); + } else { + // For non-logged-in users, save to localStorage directly + try { + // Save list width + const storedWidths = localStorage.getItem('wekan-list-widths'); + let widths = storedWidths ? JSON.parse(storedWidths) : {}; + + if (!widths[boardId]) { + widths[boardId] = {}; + } + widths[boardId][listId] = finalWidth; + + localStorage.setItem('wekan-list-widths', JSON.stringify(widths)); + + // Save list constraint + const storedConstraints = localStorage.getItem('wekan-list-constraints'); + let constraints = storedConstraints ? JSON.parse(storedConstraints) : {}; + + if (!constraints[boardId]) { + constraints[boardId] = {}; + } + constraints[boardId][listId] = listConstraint; + + localStorage.setItem('wekan-list-constraints', JSON.stringify(constraints)); + + if (process.env.DEBUG === 'true') { + } + } catch (e) { + console.warn('Error saving list width/constraint to localStorage:', e); + } + } + + e.preventDefault(); + }; + + // Mouse events + $resizeHandle.on('mousedown', startResize); + $(document).on('mousemove', doResize); + $(document).on('mouseup', stopResize); + + // Touch events for mobile + $resizeHandle.on('touchstart', startResize, { passive: false }); + $(document).on('touchmove', doResize, { passive: false }); + $(document).on('touchend', stopResize, { passive: false }); + + + // Prevent dragscroll interference + $resizeHandle.on('mousedown', (e) => { + e.stopPropagation(); + }); + + + // Reactively update resize handle visibility when auto-width changes + component.autorun(() => { + if (component.autoWidth()) { + $resizeHandle.hide(); + } else { + $resizeHandle.show(); + } + }); + + // Clean up on component destruction + component.onDestroyed(() => { + $(document).off('mousemove', doResize); + $(document).off('mouseup', stopResize); + $(document).off('touchmove', doResize); + $(document).off('touchend', stopResize); + }); + }, }).register('list'); Template.miniList.events({ diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index 662b5f187..e08684a4f 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -32,7 +32,7 @@ template(name="listBody") +addCardForm(listId=_id position="bottom") else a.open-minicard-composer.js-card-composer.js-open-inlined-form(title="{{_ 'add-card-to-bottom-of-list'}}") - i.fa.fa-plus + | ➕ template(name="spinnerList") .sk-spinner.sk-spinner-list( @@ -54,7 +54,7 @@ template(name="addCardForm") .add-controls.clearfix button.primary.confirm(type="submit") {{_ 'add'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form | ❌ .add-controls.clearfix unless currentBoard.isTemplatesBoard unless currentBoard.isTemplateBoard diff --git a/client/components/lists/listBody.js b/client/components/lists/listBody.js index 9ab4fcdc7..529c70fc8 100644 --- a/client/components/lists/listBody.js +++ b/client/components/lists/listBody.js @@ -472,6 +472,14 @@ BlazeComponent.extendComponent({ if (!this.selectedBoardId.get()) { return []; } + const board = ReactiveCache.getBoard(this.selectedBoardId.get()); + if (!board) { + return []; + } + + // Ensure default swimlane exists + board.getDefaultSwimline(); + const swimlanes = ReactiveCache.getSwimlanes( { boardId: this.selectedBoardId.get() diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 075b6282d..160be7b11 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -7,12 +7,10 @@ template(name="listHeader") else if isMiniScreen if currentList - a.list-header-left-icon.fa.fa-angle-left.js-unselect-list + a.list-header-left-icon.js-unselect-list + | ◀️ else if collapsed - a.js-collapse(title="{{_ 'uncollapse'}}") - i.fa.fa-arrow-left.list-header-uncollapse-left - i.fa.fa-arrow-right.list-header-uncollapse-right if showCardsCountForList cards.length br span.cardCount {{cardsCount}} @@ -29,6 +27,10 @@ template(name="listHeader") if showCardsCountForList cards.length span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}} else + if collapsed + a.js-collapse(title="{{_ 'uncollapse'}}") + | ⬅️ + | ➡️ div(class="{{#if collapsed}}list-rotated{{/if}}") h2.list-header-name( title="{{ moment modifiedAt 'LLL' }}" @@ -45,94 +47,97 @@ template(name="listHeader") if isMiniScreen if currentList if isWatching - i.list-header-watch-icon.fa.fa-eye + i.list-header-watch-icon | 👁️ div.list-header-menu unless currentUser.isCommentOnly if canSeeAddCard - a.js-add-card.fa.fa-plus.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}") - a.fa.fa-navicon.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") + a.js-add-card.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}") ➕ + a.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") ☰ else - a.list-header-menu-icon.fa.fa-angle-right.js-select-list - a.list-header-handle.handle.fa.fa-arrows.js-list-handle + a.list-header-menu-icon.js-select-list ▶️ + unless currentUser.isWorker + a.list-header-handle.handle.js-list-handle ↕️ else if currentUser.isBoardMember if isWatching - i.list-header-watch-icon.fa.fa-eye + i.list-header-watch-icon | 👁️ unless collapsed div.list-header-menu unless currentUser.isCommentOnly //if isBoardAdmin // a.fa.js-list-star.list-header-plus-top(class="fa-star{{#unless starred}}-o{{/unless}}") if canSeeAddCard - a.js-add-card.fa.fa-plus.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}") + a.js-add-card.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}") ➕ a.js-collapse(title="{{_ 'collapse'}}") - i.fa.fa-arrow-right.list-header-collapse-right - i.fa.fa-arrow-left.list-header-collapse-left - a.fa.fa-navicon.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") - if currentUser.isBoardAdmin - if isTouchScreenOrShowDesktopDragHandles - a.list-header-handle.handle.fa.fa-arrows.js-list-handle + | ⬅️ + | ➡️ + a.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") ☰ + if currentUser.isBoardMember + unless currentUser.isCommentOnly + unless currentUser.isWorker + a.list-header-handle.handle.js-list-handle ↕️ template(name="editListTitleForm") .list-composer input.list-name-input.full-line(type="text" value=title autofocus) .edit-controls.clearfix button.primary.confirm(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form + | ❌ template(name="listActionPopup") ul.pop-over-list li a.js-add-card.list-header-plus-bottom - i.fa.fa-plus - i.fa.fa-arrow-down + | ➕ + | ⬇️ | {{_ 'add-card-to-bottom-of-list'}} hr ul.pop-over-list li a.js-set-list-width - i.fa.fa-arrows-h + | ↔️ | {{_ 'set-list-width'}} ul.pop-over-list li a.js-toggle-watch-list if isWatching - i.fa.fa-eye + | 👁️ | {{_ 'unwatch'}} else - i.fa.fa-eye-slash + | 🙈 | {{_ 'watch'}} unless currentUser.isCommentOnly unless currentUser.isWorker ul.pop-over-list li a.js-set-color-list - i.fa.fa-paint-brush + | 🎨 | {{_ 'set-color-list'}} ul.pop-over-list if cards.length li a.js-select-cards - i.fa.fa-check-square + | ☑️ | {{_ 'list-select-cards'}} if currentUser.isBoardAdmin ul.pop-over-list li a.js-set-wip-limit - i.fa.fa-ban + | 🚫 | {{#if isWipLimitEnabled }}{{_ 'edit-wip-limit'}}{{else}}{{_ 'setWipLimitPopup-title'}}{{/if}} unless currentUser.isWorker hr ul.pop-over-list li a.js-close-list - i.fa.fa-arrow-right - i.fa.fa-archive + | ➡️ + | 📦 | {{_ 'archive-list'}} hr ul.pop-over-list li a.js-more - i.fa.fa-link + | 🔗 | {{_ 'listMorePopup-title'}} template(name="boardLists") @@ -149,7 +154,7 @@ template(name="listMorePopup") span.clearfix span {{_ 'link-list'}} = ' ' - i.fa.colorful(class="{{#if board.isPublic}}fa-globe{{else}}fa-lock{{/if}}") + | {{#if board.isPublic}}🌐{{else}}🔒{{/if}} input.inline-input(type="text" readonly value="{{ rootUrl }}") | {{_ 'added'}} span.date(title=list.createdAt) {{ moment createdAt 'LLL' }} @@ -169,7 +174,7 @@ template(name="setWipLimitPopup") ul.pop-over-list li: a.js-enable-wip-limit {{_ 'enable-wip-limit'}} if isWipLimitEnabled - i.fa.fa-check + | ✅ if isWipLimitEnabled p input.wip-limit-value(type="number" value="{{ wipLimitValue }}" min="1" max="99") @@ -197,7 +202,7 @@ template(name="setListWidthPopup") br a.js-auto-width-board( title="{{#if isAutoWidth}}{{_ 'click-to-disable-auto-width'}}{{else}}{{_ 'click-to-enable-auto-width'}}{{/if}}") - i.fa(class="fa-solid fa-{{#if isAutoWidth}}compress{{else}}expand{{/if}}") + | {{#if isAutoWidth}}🗜️{{else}}📏{{/if}} span {{_ 'auto-list-width'}} template(name="listWidthErrorPopup") @@ -211,6 +216,6 @@ template(name="setListColorPopup") // note: we use the swimlane palette to have more than just the border span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") if(isSelected color) - i.fa.fa-check + | ✅ button.primary.confirm.js-submit {{_ 'save'}} button.js-remove-color.negate.wide.right {{_ 'unset-color'}} diff --git a/client/components/main/bookmarks.jade b/client/components/main/bookmarks.jade new file mode 100644 index 000000000..27e377af4 --- /dev/null +++ b/client/components/main/bookmarks.jade @@ -0,0 +1,29 @@ +template(name="bookmarks") + .panel + h2 {{_ 'bookmarks'}} + if currentUser + if hasStarredBoards + ul + each starredBoards + li + a(href="{{pathFor 'board' id=_id slug=slug}}")= title + a.js-toggle-star(title="{{_ 'star-board-short-unstar'}}") + | ⭐ + else + p {{_ 'no-starred-boards'}} + else + p {{_ 'please-sign-in'}} + +// Desktop popup +template(name="bookmarksPopup") + ul.pop-over-list + if hasStarredBoards + each starredBoards + li + a(href="{{pathFor 'board' id=_id slug=slug}}") + | ⭐ + | #{title} + a.js-toggle-star.right(title="{{_ 'star-board-short-unstar'}}") + | ⭐ + else + li {{_ 'no-starred-boards'}} diff --git a/client/components/main/bookmarks.js b/client/components/main/bookmarks.js new file mode 100644 index 000000000..6ec110593 --- /dev/null +++ b/client/components/main/bookmarks.js @@ -0,0 +1,55 @@ +Template.bookmarks.helpers({ + hasStarredBoards() { + const user = ReactiveCache.getCurrentUser(); + if (!user) return false; + const { starredBoards = [] } = user.profile || {}; + return Array.isArray(starredBoards) && starredBoards.length > 0; + }, + starredBoards() { + const user = ReactiveCache.getCurrentUser(); + if (!user) return []; + const { starredBoards = [] } = user.profile || {}; + if (!Array.isArray(starredBoards) || starredBoards.length === 0) return []; + return Boards.find({ _id: { $in: starredBoards } }, { sort: { sort: 1 } }); + }, +}); + +Template.bookmarks.events({ + 'click .js-toggle-star'(e) { + e.preventDefault(); + const boardId = this._id; + const user = ReactiveCache.getCurrentUser(); + if (user && boardId) { + user.toggleBoardStar(boardId); + } + }, +}); + +Template.bookmarksPopup.helpers({ + hasStarredBoards() { + const user = ReactiveCache.getCurrentUser(); + if (!user) return false; + const { starredBoards = [] } = user.profile || {}; + return Array.isArray(starredBoards) && starredBoards.length > 0; + }, + starredBoards() { + const user = ReactiveCache.getCurrentUser(); + if (!user) return []; + const { starredBoards = [] } = user.profile || {}; + if (!Array.isArray(starredBoards) || starredBoards.length === 0) return []; + return Boards.find({ _id: { $in: starredBoards } }, { sort: { sort: 1 } }); + }, +}); + +Template.bookmarksPopup.events({ + 'click .js-toggle-star'(e) { + e.preventDefault(); + const boardId = this._id; + const user = ReactiveCache.getCurrentUser(); + if (user && boardId) { + user.toggleBoardStar(boardId); + } + }, +}); + + diff --git a/client/components/main/dueCards.jade b/client/components/main/dueCards.jade index a1970839e..f482c9233 100644 --- a/client/components/main/dueCards.jade +++ b/client/components/main/dueCards.jade @@ -1,23 +1,23 @@ template(name="dueCardsHeaderBar") if currentUser h1 - i.fa.fa-calendar + | 📅 | {{_ 'dueCards-title'}} .board-header-btns.left a.board-header-btn.js-due-cards-view-change(title="{{_ 'dueCardsViewChange-title'}}") - i.fa.fa-caret-down + | ▼ if $eq dueCardsView 'me' - i.fa.fa-user + | 👤 | {{_ 'dueCardsViewChange-choice-me'}} if $eq dueCardsView 'all' - i.fa.fa-users + | 👥 | {{_ 'dueCardsViewChange-choice-all'}} template(name="dueCardsModalTitle") if currentUser h2 - i.fa.fa-keyboard-o + | ⌨️ | {{_ 'dueCards-title'}} template(name="dueCards") @@ -32,7 +32,16 @@ template(name="dueCards") span.global-search-error-messages = msg else - +resultsPaged(this) + .due-cards-results-header + h1 + = resultsText + each card in dueCardsList + +resultCard(card) + else + .global-search-results-list-wrapper + .no-results + h3 {{_ 'dueCards-noResults-title'}} + p {{_ 'dueCards-noResults-description'}} template(name="dueCardsViewChangePopup") if currentUser @@ -40,18 +49,18 @@ template(name="dueCardsViewChangePopup") li with "dueCardsViewChange-choice-me" a.js-due-cards-view-me - i.fa.fa-user.colorful + | 👤 | {{_ 'dueCardsViewChange-choice-me'}} if $eq Utils.dueCardsView "me" - i.fa.fa-check + | ✅ hr li with "dueCardsViewChange-choice-all" a.js-due-cards-view-all - i.fa.fa-users.colorful + | 👥 | {{_ 'dueCardsViewChange-choice-all'}} span.sub-name +viewer | {{_ 'dueCardsViewChange-choice-all-description' }} if $eq Utils.dueCardsView "all" - i.fa.fa-check + | ✅ diff --git a/client/components/main/dueCards.js b/client/components/main/dueCards.js index da113c07a..f17bc9a74 100644 --- a/client/components/main/dueCards.js +++ b/client/components/main/dueCards.js @@ -1,13 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; -import { CardSearchPagedComponent } from '../../lib/cardSearch'; -import { - OPERATOR_HAS, - OPERATOR_SORT, - OPERATOR_USER, - ORDER_ASCENDING, - PREDICATE_DUE_AT, -} from '../../../config/search-const'; -import { QueryParams } from '../../../config/query-classes'; +import { BlazeComponent } from 'meteor/peerlibrary:blaze-components'; +import { TAPi18n } from '/imports/i18n'; // const subManager = new SubsManager(); @@ -15,7 +8,7 @@ BlazeComponent.extendComponent({ dueCardsView() { // eslint-disable-next-line no-console // console.log('sort:', Utils.dueCardsView()); - return Utils.dueCardsView(); + return Utils && Utils.dueCardsView ? Utils.dueCardsView() : 'me'; }, events() { @@ -31,6 +24,47 @@ Template.dueCards.helpers({ userId() { return Meteor.userId(); }, + dueCardsList() { + const component = BlazeComponent.getComponentForElement(this.firstNode); + if (component && component.dueCardsList) { + return component.dueCardsList(); + } + return []; + }, + hasResults() { + const component = BlazeComponent.getComponentForElement(this.firstNode); + if (component && component.hasResults) { + return component.hasResults.get(); + } + return false; + }, + searching() { + const component = BlazeComponent.getComponentForElement(this.firstNode); + if (component && component.isLoading) { + return component.isLoading.get(); + } + return true; // Show loading by default + }, + hasQueryErrors() { + return false; // No longer using search, so always false + }, + errorMessages() { + return []; // No longer using search, so always empty + }, + cardsCount() { + const component = BlazeComponent.getComponentForElement(this.firstNode); + if (component && component.cardsCount) { + return component.cardsCount(); + } + return 0; + }, + resultsText() { + const component = BlazeComponent.getComponentForElement(this.firstNode); + if (component && component.resultsText) { + return component.resultsText(); + } + return ''; + }, }); BlazeComponent.extendComponent({ @@ -38,12 +72,16 @@ BlazeComponent.extendComponent({ return [ { 'click .js-due-cards-view-me'() { - Utils.setDueCardsView('me'); + if (Utils && Utils.setDueCardsView) { + Utils.setDueCardsView('me'); + } Popup.back(); }, 'click .js-due-cards-view-all'() { - Utils.setDueCardsView('all'); + if (Utils && Utils.setDueCardsView) { + Utils.setDueCardsView('all'); + } Popup.back(); }, }, @@ -51,61 +89,162 @@ BlazeComponent.extendComponent({ }, }).register('dueCardsViewChangePopup'); -class DueCardsComponent extends CardSearchPagedComponent { +class DueCardsComponent extends BlazeComponent { onCreated() { super.onCreated(); - - const queryParams = new QueryParams(); - queryParams.addPredicate(OPERATOR_HAS, { - field: PREDICATE_DUE_AT, - exists: true, - }); - // queryParams[OPERATOR_LIMIT] = 5; - queryParams.addPredicate(OPERATOR_SORT, { - name: PREDICATE_DUE_AT, - order: ORDER_ASCENDING, + + this._cachedCards = null; + this._cachedTimestamp = null; + this.subscriptionHandle = null; + this.isLoading = new ReactiveVar(true); + this.hasResults = new ReactiveVar(false); + this.searching = new ReactiveVar(false); + + // Subscribe to the optimized due cards publication + this.autorun(() => { + const allUsers = this.dueCardsView() === 'all'; + if (this.subscriptionHandle) { + this.subscriptionHandle.stop(); + } + this.subscriptionHandle = Meteor.subscribe('dueCards', allUsers); + + // Update loading state based on subscription + this.autorun(() => { + if (this.subscriptionHandle && this.subscriptionHandle.ready()) { + if (process.env.DEBUG === 'true') { + console.log('dueCards: subscription ready, loading data...'); + } + this.isLoading.set(false); + const cards = this.dueCardsList(); + this.hasResults.set(cards && cards.length > 0); + } else { + if (process.env.DEBUG === 'true') { + console.log('dueCards: subscription not ready, showing loading...'); + } + this.isLoading.set(true); + this.hasResults.set(false); + } + }); }); + } - if (Utils.dueCardsView() !== 'all') { - queryParams.addPredicate(OPERATOR_USER, ReactiveCache.getCurrentUser().username); + onDestroyed() { + super.onDestroyed(); + if (this.subscriptionHandle) { + this.subscriptionHandle.stop(); } - - this.runGlobalSearch(queryParams); } dueCardsView() { // eslint-disable-next-line no-console //console.log('sort:', Utils.dueCardsView()); - return Utils.dueCardsView(); + return Utils && Utils.dueCardsView ? Utils.dueCardsView() : 'me'; } sortByBoard() { return this.dueCardsView() === 'board'; } + hasResults() { + return this.hasResults.get(); + } + + cardsCount() { + const cards = this.dueCardsList(); + return cards ? cards.length : 0; + } + + resultsText() { + const count = this.cardsCount(); + if (count === 1) { + return TAPi18n.__('one-card-found'); + } else { + // Get the translated text and manually replace %s with the count + const baseText = TAPi18n.__('n-cards-found'); + const result = baseText.replace('%s', count); + + if (process.env.DEBUG === 'true') { + console.log('dueCards: base text:', baseText, 'count:', count, 'result:', result); + } + return result; + } + } + dueCardsList() { - const results = this.getResults(); - console.log('results:', results); - const cards = []; - if (results) { - results.forEach(card => { - cards.push(card); + // Check if subscription is ready + if (!this.subscriptionHandle || !this.subscriptionHandle.ready()) { + if (process.env.DEBUG === 'true') { + console.log('dueCards client: subscription not ready'); + } + return []; + } + + // Use cached results if available to avoid expensive re-sorting + if (this._cachedCards && this._cachedTimestamp && (Date.now() - this._cachedTimestamp < 5000)) { + if (process.env.DEBUG === 'true') { + console.log('dueCards client: using cached results,', this._cachedCards.length, 'cards'); + } + return this._cachedCards; + } + + // Get cards directly from the subscription (already sorted by the publication) + const cards = ReactiveCache.getCards({ + type: 'cardType-card', + archived: false, + dueAt: { $exists: true, $nin: [null, ''] } + }); + + if (process.env.DEBUG === 'true') { + console.log('dueCards client: found', cards.length, 'cards with due dates'); + console.log('dueCards client: cards details:', cards.map(c => ({ + id: c._id, + title: c.title, + dueAt: c.dueAt, + boardId: c.boardId, + members: c.members, + assignees: c.assignees, + userId: c.userId + }))); + } + + // Filter cards based on user view preference + const allUsers = this.dueCardsView() === 'all'; + const currentUser = ReactiveCache.getCurrentUser(); + let filteredCards = cards; + + if (process.env.DEBUG === 'true') { + console.log('dueCards client: current user:', currentUser ? currentUser._id : 'none'); + console.log('dueCards client: showing all users:', allUsers); + } + + if (!allUsers && currentUser) { + filteredCards = cards.filter(card => { + const isMember = card.members && card.members.includes(currentUser._id); + const isAssignee = card.assignees && card.assignees.includes(currentUser._id); + const isAuthor = card.userId === currentUser._id; + const matches = isMember || isAssignee || isAuthor; + + if (process.env.DEBUG === 'true' && matches) { + console.log('dueCards client: card matches user:', card.title, { isMember, isAssignee, isAuthor }); + } + + return matches; }); } - cards.sort((a, b) => { - const x = a.dueAt === null ? new Date('2100-12-31') : a.dueAt; - const y = b.dueAt === null ? new Date('2100-12-31') : b.dueAt; + if (process.env.DEBUG === 'true') { + console.log('dueCards client: filtered to', filteredCards.length, 'cards'); + } - if (x > y) return 1; - else if (x < y) return -1; + // Cache the results for 5 seconds to avoid re-filtering on every render + this._cachedCards = filteredCards; + this._cachedTimestamp = Date.now(); - return 0; - }); + // Update reactive variables + this.hasResults.set(filteredCards && filteredCards.length > 0); + this.isLoading.set(false); - // eslint-disable-next-line no-console - console.log('cards:', cards); - return cards; + return filteredCards; } } diff --git a/client/components/main/editor.jade b/client/components/main/editor.jade index 4d7117ca3..802a8745d 100644 --- a/client/components/main/editor.jade +++ b/client/components/main/editor.jade @@ -1,6 +1,8 @@ template(name="editor") - a.fa.fa-brands.fa-markdown(title="{{_ 'convert-to-markdown'}}") - a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}") + a(title="{{_ 'convert-to-markdown'}}") + | 📝 + a(title="{{_ 'copy-text-to-clipboard'}}") + | 📋 span.copied-tooltip {{_ 'copied'}} textarea.editor( dir="auto" diff --git a/client/components/main/globalSearch.jade b/client/components/main/globalSearch.jade index 4b1faa718..da00bbf03 100644 --- a/client/components/main/globalSearch.jade +++ b/client/components/main/globalSearch.jade @@ -1,20 +1,21 @@ template(name="globalSearchHeaderBar") if currentUser h1 - i.fa.fa-search + | 🔍 | {{_ 'globalSearch-title'}} template(name="globalSearchModalTitle") if currentUser h2 - i.fa.fa-keyboard-o + | ⌨️ | {{_ 'globalSearch-title'}} template(name="resultsPaged") if resultsHeading.get h1 = resultsHeading.get - a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}") + a(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}") + | 🔗 each card in results.get +resultCard(card) table.global-search-footer @@ -41,7 +42,8 @@ template(name="globalSearch") value="{{ query.get }}" autofocus dir="auto" ) - a.js-new-search.fa.fa-eraser + a.js-new-search + | 🧹 if debug.get.show h1 Debug if debug.get.showSelector diff --git a/client/components/main/header.css b/client/components/main/header.css index cb6be4e88..609941320 100644 --- a/client/components/main/header.css +++ b/client/components/main/header.css @@ -58,7 +58,7 @@ float: left; overflow: hidden; line-height: 28px; - margin: 0 2px; + margin: 0 12px; } #header #header-main-bar .board-header-btn i.fa { float: left; @@ -100,8 +100,9 @@ z-index: 1000; padding: 10px 0px; align-items: center; - flex-wrap: wrap; /* Allow wrapping on mobile */ - min-height: 28px; /* Allow height to grow */ + flex-wrap: nowrap; /* Prevent wrapping to keep single row */ + min-height: 28px; + overflow: hidden; /* Prevent content from overflowing */ } #header-quick-access .home-icon { display: flex; @@ -167,13 +168,39 @@ white-space: nowrap; padding: 10px; margin: -10px; + flex: 1; /* Take up available space */ + min-width: 0; /* Allow shrinking below content size */ + display: flex; /* Use flexbox for better control */ + align-items: center; + scrollbar-width: thin; /* Firefox */ + scrollbar-color: rgba(255, 255, 255, 0.3) transparent; /* Firefox */ +} + +/* Webkit scrollbar styling for better UX */ +#header-quick-access ul.header-quick-access-list::-webkit-scrollbar { + height: 4px; +} + +#header-quick-access ul.header-quick-access-list::-webkit-scrollbar-track { + background: transparent; +} + +#header-quick-access ul.header-quick-access-list::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.3); + border-radius: 2px; +} + +#header-quick-access ul.header-quick-access-list::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.5); } #header-quick-access ul.header-quick-access-list li { - display: inline; + display: inline-block; /* Keep inline-block for proper spacing */ width: auto; color: #d9d9d9; padding: 12px 0px; margin: -10px 0px; + flex-shrink: 0; /* Prevent items from shrinking */ + white-space: nowrap; /* Prevent text wrapping within items */ } #header-quick-access ul.header-quick-access-list li a { padding: 12px 10px; @@ -220,6 +247,7 @@ margin: 0; margin-top: 1px; } + #header-quick-access #header-user-bar .header-user-bar-name, #header-quick-access #header-help { margin: 4px 8px 0 0; @@ -314,7 +342,8 @@ } /* Make zoom input wider on all mobile screens */ - @media screen and (max-width: 800px) { + @media screen and (max-width: 800px), + screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) { #header-quick-access .zoom-controls .zoom-input { min-width: 50px !important; /* Wider on mobile */ width: 50px !important; /* Fixed width to show all numbers */ @@ -424,7 +453,8 @@ margin: 6px 5px 0; width: 12px; } -@media screen and (max-width: 800px) { +@media screen and (max-width: 800px), + screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) { #header #header-main-bar { height: 40px; } @@ -446,6 +476,8 @@ transition: background-color 0.4s; width: 100%; z-index: 30; + flex-wrap: nowrap !important; /* Force single row on mobile */ + overflow: hidden; /* Prevent content overflow */ } /* Mobile home icon styling */ @@ -489,11 +521,12 @@ screen and (max-width: 800px) and (orientation: portrait), screen and (max-width: 800px) and (orientation: landscape) { #header-quick-access { - height: auto !important; /* Allow height to grow */ + height: 48px !important; /* Fixed height for mobile */ min-height: 48px !important; /* Minimum height for mobile */ - flex-wrap: wrap !important; /* Force wrapping */ - align-items: flex-start !important; /* Align to top when wrapping */ + flex-wrap: nowrap !important; /* Force single row */ + align-items: center !important; /* Center align items */ padding: 8px 0px !important; /* Adjust padding for mobile */ + overflow: hidden !important; /* Prevent content overflow */ } #header-quick-access { font-size: 2em !important; /* 2x bigger base font size */ diff --git a/client/components/main/header.jade b/client/components/main/header.jade index 0ceb2ae9d..1ac11f189 100644 --- a/client/components/main/header.jade +++ b/client/components/main/header.jade @@ -9,10 +9,10 @@ template(name="header") // Home icon - always at left side of logo span.home-icon.allBoards a(href="{{pathFor 'home'}}") - span.fa.fa-home + | 🏠 | {{_ 'all-boards'}} - // Logo - always visible in desktop mode + // Logo - visible; on mobile constrained by CSS unless currentSetting.hideLogo if currentSetting.customTopLeftCornerLogoImageUrl if currentSetting.customTopLeftCornerLogoLinkUrl @@ -80,14 +80,16 @@ template(name="header") .mobile-mode-toggle a.board-header-btn.js-mobile-mode-toggle(title="{{_ 'mobile-desktop-toggle'}}" class="{{#if mobileMode}}mobile-active{{else}}desktop-active{{/if}}") - i.fa.fa-mobile.mobile-icon(class="{{#if mobileMode}}active{{/if}}") - i.fa.fa-desktop.desktop-icon(class="{{#unless mobileMode}}active{{/unless}}") + i.mobile-icon(class="{{#if mobileMode}}active{{/if}}") 📱 + i.desktop-icon(class="{{#unless mobileMode}}active{{/unless}}") 🖥️ + + // Notifications +notifications if currentSetting.customHelpLinkUrl #header-help a(href="{{currentSetting.customHelpLinkUrl}}", title="{{_ 'help'}}", target="_blank", rel="noopener noreferrer") - span.fa.fa-question + | ❓ +headerUserBar @@ -106,15 +108,15 @@ template(name="header") if hasAnnouncement .announcement p - i.fa.fa-bullhorn + | 📢 +viewer | #{announcement} - i.fa.fa-times-circle.js-close-announcement + | ❌ template(name="offlineWarning") .offline-warning p - i.fa.fa-warning + | ⚠️ | {{_ 'app-is-offline'}} a.app-try-reconnect {{_ 'app-try-reconnect'}} diff --git a/client/components/main/header.js b/client/components/main/header.js index f56a47f44..99c3aabc1 100644 --- a/client/components/main/header.js +++ b/client/components/main/header.js @@ -104,6 +104,9 @@ Template.header.events({ const currentMode = Utils.getMobileMode(); Utils.setMobileMode(!currentMode); }, + 'click .js-open-bookmarks'(evt) { + // Already added but ensure single definition -- safe guard + }, 'click .js-close-announcement'() { $('.announcement').hide(); }, @@ -124,6 +127,14 @@ Template.header.events({ location.reload(); } }, + 'click .js-open-bookmarks'(evt) { + // Desktop: open popup, Mobile: route to page + if (Utils.isMiniScreen()) { + FlowRouter.go('bookmarks'); + } else { + Popup.open('bookmarksPopup')(evt); + } + }, }); Template.offlineWarning.events({ diff --git a/client/components/main/keyboardShortcuts.jade b/client/components/main/keyboardShortcuts.jade index bde408195..1eee1d220 100644 --- a/client/components/main/keyboardShortcuts.jade +++ b/client/components/main/keyboardShortcuts.jade @@ -1,12 +1,12 @@ template(name="shortcutsHeaderBar") h1 a.back-btn(href="{{pathFor 'home'}}") - i.fa.fa-chevron-left + | ◀️ | {{_ 'keyboard-shortcuts'}} template(name="shortcutsModalTitle") h2 - i.fa.fa-keyboard-o + | ⌨️ | {{_ 'keyboard-shortcuts'}} template(name="keyboardShortcuts") diff --git a/client/components/main/layouts.css b/client/components/main/layouts.css index 5cc59516b..fb8f4bf5c 100644 --- a/client/components/main/layouts.css +++ b/client/components/main/layouts.css @@ -52,9 +52,15 @@ input, select, textarea, button { - font: clamp(12px, 2.5vw, 16px) Roboto, Poppins, "Helvetica Neue", Arial, Helvetica, sans-serif; - line-height: 1.3; + font: clamp(14px, 2.5vw, 18px) Roboto, Poppins, "Helvetica Neue", Arial, Helvetica, sans-serif; + line-height: 1.4; color: #4d4d4d; + /* Improve text rendering */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + /* Better text selection */ + -webkit-user-select: text; + user-select: text; } html { font-size: 100%; @@ -460,20 +466,291 @@ a:not(.disabled).is-active i.fa { .no-scrollbars::-webkit-scrollbar { display: none !important; } -@media screen and (max-width: 800px) { +/* ======================================== + MOBILE & TABLET RESPONSIVE IMPROVEMENTS + ======================================== */ + +/* Mobile devices (up to 800px) and all iPhone models */ +@media screen and (max-width: 800px), + screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) and (orientation: landscape), + screen and (max-device-width: 932px) and (-webkit-min-device-pixel-ratio: 3) and (orientation: portrait) { #content { margin: 1px 0px 0px 0px; height: calc(100% - 0px); + /* Improve touch scrolling */ + -webkit-overflow-scrolling: touch; } #content > .wrapper { margin-top: 0px; + padding: 8px; } .wrapper { height: calc(100% - 31px); margin: 0px; + padding: 8px; } .panel-default { - width: 83vw; + width: 95vw; + max-width: 95vw; + margin: 0 auto; + } + + /* Improve touch targets */ + button, .btn, .js-toggle, .js-color-choice, .js-reaction, .close { + min-height: 44px; + min-width: 44px; + padding: 12px 16px; + font-size: 16px; /* Prevent zoom on iOS */ + touch-action: manipulation; + } + + /* Form elements */ + input, select, textarea { + font-size: 16px; /* Prevent zoom on iOS */ + padding: 12px; + min-height: 44px; + touch-action: manipulation; + } + + /* Cards and lists */ + .minicard { + min-height: 48px; + padding: 12px; + margin-bottom: 8px; + touch-action: manipulation; + } + + .list { + margin: 0 8px; + min-width: 280px; + } + + /* Board canvas */ + .board-canvas { + padding: 8px; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + + /* Header mobile layout */ + #header { + padding: 8px; + /* Keep top bar on a single row on small screens */ + flex-wrap: nowrap; + align-items: center; + gap: 8px; + } + + #header-quick-access { + /* Keep quick-access items in one row */ + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; + width: 100%; + } + + /* Hide elements that should move to the hamburger menu on mobile */ + #header-quick-access .header-quick-access-list, + #header-quick-access #header-help { + display: none !important; + } + + /* Show only the home icon (hide the trailing text) on mobile */ + #header-quick-access .home-icon a { + display: inline-flex; + align-items: center; + max-width: 28px; /* enough to display the icon */ + overflow: hidden; + white-space: nowrap; + } + + /* Hide text in home icon on mobile, show only icon */ + #header-quick-access .home-icon a span:not(.fa) { + display: none !important; + } + + /* Ensure proper spacing for mobile header elements */ + #header-quick-access .zoom-controls { + margin-left: auto; + margin-right: 8px; + } + + .mobile-mode-toggle { + margin-right: 8px; + } + + #header-user-bar { + margin-left: auto; + } + + /* Ensure header elements don't wrap on very small screens */ + #header-quick-access { + min-width: 0; /* Allow flexbox to shrink */ + } + + /* Make sure logo doesn't take too much space on mobile */ + #header-quick-access img { + max-height: 24px; + max-width: 120px; + } + + /* Ensure zoom controls are compact on mobile */ + .zoom-controls .zoom-level { + padding: 4px 8px; + font-size: 12px; + } + + /* Modal mobile optimization */ + #modal .modal-content, + #modal .modal-content-wide { + width: 95vw; + max-width: 95vw; + margin: 2vh auto; + padding: 16px; + max-height: 90vh; + overflow-y: auto; + } + + /* Table mobile optimization */ + table { + font-size: 14px; + width: 100%; + display: block; + overflow-x: auto; + white-space: nowrap; + -webkit-overflow-scrolling: touch; + } + + /* Admin panel mobile optimization */ + .setting-content .content-body { + flex-direction: column; + gap: 16px; + padding: 8px; + } + + .setting-content .content-body .side-menu { + width: 100%; + order: 2; + } + + .setting-content .content-body .main-body { + order: 1; + min-height: 60vh; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} + +/* Tablet devices (768px - 1024px) */ +@media screen and (min-width: 768px) and (max-width: 1024px) { + #content > .wrapper { + padding: 12px; + } + + .wrapper { + padding: 12px; + } + + .panel-default { + width: 90vw; + max-width: 90vw; + } + + /* Touch-friendly but more compact */ + button, .btn, .js-toggle, .js-color-choice, .js-reaction, .close { + min-height: 48px; + min-width: 48px; + padding: 10px 14px; + } + + .minicard { + min-height: 40px; + padding: 10px; + } + + .list { + margin: 0 12px; + min-width: 300px; + } + + .board-canvas { + padding: 12px; + } + + #header { + padding: 12px 16px; + } + + #modal .modal-content { + width: 80vw; + max-width: 600px; + } + + #modal .modal-content-wide { + width: 90vw; + max-width: 800px; + } + + .setting-content .content-body { + gap: 20px; + } + + .setting-content .content-body .side-menu { + width: 250px; + } +} + +/* Large displays and digital signage (1920px+) */ +@media screen and (min-width: 1920px) { + body { + font-size: 18px; + } + + button, .btn, .js-toggle, .js-color-choice, .js-reaction, .close { + min-height: 56px; + min-width: 56px; + padding: 16px 20px; + font-size: 18px; + } + + .minicard { + min-height: 56px; + padding: 16px; + font-size: 18px; + } + + .list { + margin: 0 8px; + min-width: 360px; + } + + .board-canvas { + padding: 0; + } + + #header { + padding: 0 8px; + } + + #content > .wrapper { + padding: 0; + } + + #modal .modal-content { + width: 600px; + } + + #modal .modal-content-wide { + width: 1000px; + } + + .setting-content .content-body { + gap: 32px; + } + + .setting-content .content-body .side-menu { + width: 320px; } } .inline-input { diff --git a/client/components/main/layouts.jade b/client/components/main/layouts.jade index 5d9e7145c..469524e04 100644 --- a/client/components/main/layouts.jade +++ b/client/components/main/layouts.jade @@ -2,7 +2,7 @@ template(name="main") html(lang="{{TAPi18n.getLanguage}}") head title - meta(name="viewport" content="width=device-width, initial-scale=1") + meta(name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, user-scalable=yes") meta(http-equiv="X-UA-Compatible" content="IE=edge") //- XXX We should use pathFor in the following `href` to support the case where the application is deployed with a path prefix, but it seems to be @@ -77,19 +77,21 @@ template(name="defaultLayout") | {{{afterBodyStart}}} +Template.dynamic(template=content) | {{{beforeBodyEnd}}} + +migrationProgress + +boardConversionProgress if (Modal.isOpen) #modal .overlay if (Modal.isWide) .modal-content-wide.modal-container a.modal-close-btn.js-close-modal - i.fa.fa-times-thin + | ❌ +Template.dynamic(template=Modal.getHeaderName) +Template.dynamic(template=Modal.getTemplateName) else .modal-content.modal-container a.modal-close-btn.js-close-modal - i.fa.fa-times-thin + | ❌ +Template.dynamic(template=Modal.getHeaderName) +Template.dynamic(template=Modal.getTemplateName) diff --git a/client/components/main/layouts.js b/client/components/main/layouts.js index eff1eba4a..d2d535207 100644 --- a/client/components/main/layouts.js +++ b/client/components/main/layouts.js @@ -92,6 +92,18 @@ Template.userFormsLayout.onRendered(() => { if (loginInput && loginInput.name && (loginInput.name.toLowerCase().includes('user') || loginInput.name.toLowerCase().includes('email'))) { loginInput.setAttribute('autocomplete', 'username email'); } + + // Add autocomplete attributes to password fields for WCAG compliance + const passwordInputs = document.querySelectorAll('input[type="password"]'); + passwordInputs.forEach(input => { + if (input.name && input.name.includes('password')) { + if (input.name.includes('password_again') || input.name.includes('new_password')) { + input.setAttribute('autocomplete', 'new-password'); + } else { + input.setAttribute('autocomplete', 'current-password'); + } + } + }); }); }); diff --git a/client/components/main/myCards.jade b/client/components/main/myCards.jade index df0199ac6..86105ced4 100644 --- a/client/components/main/myCards.jade +++ b/client/components/main/myCards.jade @@ -3,23 +3,23 @@ template(name="myCardsHeaderBar") h1 //a.back-btn(href="{{pathFor 'home'}}") // i.fa.fa-chevron-left - i.fa.fa-list + | 📋 | {{_ 'my-cards'}} .board-header-btns.left a.board-header-btn.js-my-cards-view-change(title="{{_ 'myCardsViewChange-title'}}") - i.fa.fa-caret-down + | ▼ if $eq myCardsView 'boards' - i.fa.fa-trello + | 📋 | {{_ 'myCardsViewChange-choice-boards'}} if $eq myCardsView 'table' - i.fa.fa-table + | 📊 | {{_ 'myCardsViewChange-choice-table'}} template(name="myCardsModalTitle") if currentUser h2 - i.fa.fa-keyboard-o + | ⌨️ | {{_ 'my-cards'}} template(name="myCards") @@ -102,15 +102,15 @@ template(name="myCardsViewChangePopup") li with "myCardsViewChange-choice-boards" a.js-my-cards-view-boards - i.fa.fa-trello.colorful + | 📋 | {{_ 'myCardsViewChange-choice-boards'}} if $eq Utils.myCardsView "boards" - i.fa.fa-check + | ✅ hr li with "myCardsViewChange-choice-table" a.js-my-cards-view-table - i.fa.fa-table.colorful + | 📊 | {{_ 'myCardsViewChange-choice-table'}} if $eq Utils.myCardsView "table" - i.fa.fa-check + | ✅ diff --git a/client/components/main/popup.css b/client/components/main/popup.css index 0fbdd195a..dafbd2576 100644 --- a/client/components/main/popup.css +++ b/client/components/main/popup.css @@ -5,7 +5,8 @@ border-bottom-color: #c2c2c2; box-shadow: 0 0.2vh 0.8vh rgba(0,0,0,0.3); position: absolute; - width: min(300px, 40vw); + /* Wider default to fit full color palette */ + width: min(380px, 55vw); z-index: 99999; margin-top: 0.7vh; } @@ -72,23 +73,321 @@ } .pop-over .content-wrapper { width: 100%; - overflow: hidden; + max-height: calc(70vh + 20px); + overflow-y: auto; + overflow-x: hidden; +} + +/* Allow dynamic max-height to override default constraint */ +.pop-over[style*="max-height"] .content-wrapper { + max-height: inherit; } .pop-over .content-container { - width: 5000px; - max-height: 70vh; + width: 100%; + max-height: calc(70vh + 20px); transition: transform 0.2s; } + +/* Allow dynamic max-height to override default constraint for content-container */ +.pop-over[style*="max-height"] .content-container { + max-height: inherit; +} + +/* Admin edit popups: use full height */ +.pop-over[data-popup="editUser"], +.pop-over[data-popup="editOrg"], +.pop-over[data-popup="editTeam"] { + height: calc(100vh - 20px) !important; + max-height: calc(100vh - 20px) !important; +} + +.pop-over[data-popup="editUser"] .content-wrapper, +.pop-over[data-popup="editOrg"] .content-wrapper, +.pop-over[data-popup="editTeam"] .content-wrapper { + max-height: calc(100vh - 80px) !important; /* Subtract header height */ + height: calc(100vh - 80px) !important; + overflow-y: auto !important; +} + +.pop-over[data-popup="editUser"] .content-container, +.pop-over[data-popup="editOrg"] .content-container, +.pop-over[data-popup="editTeam"] .content-container { + max-height: calc(100vh - 80px) !important; /* Subtract header height */ + height: calc(100vh - 80px) !important; +} + +/* Ensure language popup list can scroll properly */ +.pop-over .pop-over-list { + max-height: none; + overflow: visible; +} + +/* Specific styling for language popup list */ +.pop-over[data-popup="changeLanguage"] .pop-over-list { + max-height: none; + overflow: visible; + height: auto; + flex: 1; +} + +/* Ensure content div in language popup contains all items */ +.pop-over[data-popup="changeLanguage"] .content { + height: auto; + min-height: 100%; + display: flex; + flex-direction: column; +} + +/* Allow dynamic height for Change Language popup */ +.pop-over[data-popup="changeLanguage"] .content-wrapper { + max-height: inherit; /* Use dynamic height from JavaScript */ +} + +.pop-over[data-popup="changeLanguage"] .content-container { + max-height: inherit; /* Use dynamic height from JavaScript */ +} + +/* Make language popup extend to bottom of browser window */ +.pop-over[data-popup="changeLanguage"] { + height: calc(100vh - 30px); + min-height: 300px; + /* Adjust positioning to move popup 30px higher */ + transform: translateY(-30px); +} + +.pop-over[data-popup="changeLanguage"] .content-wrapper { + height: calc(100% - 50px); /* Subtract header height more precisely */ + min-height: 250px; + overflow-y: auto; + max-height: none; /* Remove any max-height constraints */ + display: flex; + flex-direction: column; +} + +.pop-over[data-popup="changeLanguage"] .content-container { + height: auto; /* Let content determine height */ + min-height: 250px; + max-height: none; /* Remove any max-height constraints */ + flex: 1; + display: flex; + flex-direction: column; +} + +/* Date popup sizing for native HTML inputs */ +.pop-over[data-popup="editCardReceivedDatePopup"], +.pop-over[data-popup="editCardStartDatePopup"], +.pop-over[data-popup="editCardDueDatePopup"], +.pop-over[data-popup="editCardEndDatePopup"], +.pop-over[data-popup*="Date"] { + width: min(400px, 90vw) !important; /* Smaller width for native inputs */ + min-width: 350px !important; + max-height: 80vh !important; +} + +.pop-over[data-popup="editCardReceivedDatePopup"] .content-wrapper, +.pop-over[data-popup="editCardStartDatePopup"] .content-wrapper, +.pop-over[data-popup="editCardDueDatePopup"] .content-wrapper, +.pop-over[data-popup="editCardEndDatePopup"] .content-wrapper, +.pop-over[data-popup*="Date"] .content-wrapper { + max-height: 60vh !important; + overflow-y: auto !important; +} + +.pop-over[data-popup="editCardReceivedDatePopup"] .content-container, +.pop-over[data-popup="editCardStartDatePopup"] .content-container, +.pop-over[data-popup="editCardDueDatePopup"] .content-container, +.pop-over[data-popup="editCardEndDatePopup"] .content-container, +.pop-over[data-popup*="Date"] .content-container { + max-height: 60vh !important; +} + +/* Native HTML input styling */ +.pop-over[data-popup*="Date"] .datepicker-container { + width: 100% !important; + padding: 15px !important; +} + +.pop-over[data-popup*="Date"] .datepicker-container .fields { + display: flex !important; + gap: 15px !important; + margin-bottom: 15px !important; +} + +.pop-over[data-popup*="Date"] .datepicker-container .fields .left, +.pop-over[data-popup*="Date"] .datepicker-container .fields .right { + flex: 1 !important; + width: auto !important; +} + +.pop-over[data-popup*="Date"] .datepicker-container label { + display: block !important; + margin-bottom: 5px !important; + font-weight: bold !important; +} + +.pop-over[data-popup*="Date"] .datepicker-container input[type="date"], +.pop-over[data-popup*="Date"] .datepicker-container input[type="time"] { + width: 100% !important; + padding: 8px !important; + border: 1px solid #ccc !important; + border-radius: 4px !important; + font-size: 14px !important; + box-sizing: border-box !important; +} + +.pop-over[data-popup*="Date"] .datepicker-container input[type="date"]:focus, +.pop-over[data-popup*="Date"] .datepicker-container input[type="time"]:focus { + outline: none !important; + border-color: #007cba !important; + box-shadow: 0 0 0 2px rgba(0, 124, 186, 0.2) !important; +} + +/* Ensure date popup buttons stay within popup boundaries */ +.pop-over[data-popup="editCardReceivedDatePopup"] .content, +.pop-over[data-popup="editCardStartDatePopup"] .content, +.pop-over[data-popup="editCardDueDatePopup"] .content, +.pop-over[data-popup="editCardEndDatePopup"] .content, +.pop-over[data-popup*="Date"] .content { + max-height: 60vh !important; /* Leave space for buttons */ + overflow-y: auto !important; + padding-bottom: 100px !important; /* More space for buttons */ + margin-bottom: 0 !important; +} + +.pop-over[data-popup="editCardReceivedDatePopup"] .datepicker-container, +.pop-over[data-popup="editCardStartDatePopup"] .datepicker-container, +.pop-over[data-popup="editCardDueDatePopup"] .datepicker-container, +.pop-over[data-popup="editCardEndDatePopup"] .datepicker-container, +.pop-over[data-popup*="Date"] .datepicker-container { + max-height: 50vh !important; /* Limit calendar height */ + overflow-y: auto !important; + margin-bottom: 20px !important; /* Space before buttons */ +} + +/* Ensure buttons are properly positioned */ +.pop-over[data-popup="editCardReceivedDatePopup"] .edit-date, +.pop-over[data-popup="editCardStartDatePopup"] .edit-date, +.pop-over[data-popup="editCardDueDatePopup"] .edit-date, +.pop-over[data-popup="editCardEndDatePopup"] .edit-date, +.pop-over[data-popup*="Date"] .edit-date { + display: flex !important; + flex-direction: column !important; + height: 100% !important; +} + +.pop-over[data-popup="editCardReceivedDatePopup"] .edit-date .fields, +.pop-over[data-popup="editCardStartDatePopup"] .edit-date .fields, +.pop-over[data-popup="editCardDueDatePopup"] .edit-date .fields, +.pop-over[data-popup="editCardEndDatePopup"] .edit-date .fields, +.pop-over[data-popup*="Date"] .edit-date .fields { + flex-shrink: 0 !important; + margin-bottom: 15px !important; +} + +.pop-over[data-popup="editCardReceivedDatePopup"] .edit-date .js-datepicker, +.pop-over[data-popup="editCardStartDatePopup"] .edit-date .js-datepicker, +.pop-over[data-popup="editCardDueDatePopup"] .edit-date .js-datepicker, +.pop-over[data-popup="editCardEndDatePopup"] .edit-date .js-datepicker, +.pop-over[data-popup*="Date"] .edit-date .js-datepicker { + flex: 1 !important; + overflow-y: auto !important; +} + + + +.pop-over[data-popup="editCardReceivedDatePopup"] .edit-date button, +.pop-over[data-popup="editCardStartDatePopup"] .edit-date button, +.pop-over[data-popup="editCardDueDatePopup"] .edit-date button, +.pop-over[data-popup="editCardEndDatePopup"] .edit-date button, +.pop-over[data-popup*="Date"] .edit-date button { + flex-shrink: 0 !important; + margin-top: 15px !important; + position: relative !important; + z-index: 10 !important; +} .pop-over .content-container .content { - width: min(280px, 37vw); + /* Match wider popover, leave padding */ + width: 100%; padding: 0 1.3vw 1.3vh; - float: left; + box-sizing: border-box; + /* Ensure content is not shifted left */ + margin-left: 0 !important; + transform: none !important; +} + +/* Utility: remove left gutter inside specific popups */ +.pop-over .content .flush-left { + margin-left: 0; + padding-left: 0; + width: 100%; +} + +/* Swimlane popups: remove left gutter, align content fully left */ +.pop-over .content form.swimlane-color-popup, +.pop-over .content .swimlane-height-popup { + margin-left: 0; + padding-left: 0; + width: 100%; +} + +/* Color selection popups: ensure proper alignment */ +.pop-over .content form.swimlane-color-popup .palette-colors, +.pop-over .content form.edit-label .palette-colors, +.pop-over .content form.create-label .palette-colors { + margin-left: 0; + padding-left: 0; + width: 100%; +} + +/* Color palette items: ensure proper positioning */ +.pop-over .content .palette-colors .palette-color { + margin-left: 0; + margin-right: 2px; + margin-bottom: 2px; +} + +/* Global fix for all popup content to prevent left shifting */ +.pop-over .content * { + margin-left: 0 !important; + transform: none !important; +} + +/* Override any potential left shifting for specific elements */ +.pop-over .content form, +.pop-over .content .palette-colors, +.pop-over .content .pop-over-list, +.pop-over .content .flush-left { + margin-left: 0 !important; + padding-left: 0 !important; + transform: none !important; +} + +/* Fix popup depth containers that cause left shifting */ +.pop-over .popup-container-depth-1, +.pop-over .popup-container-depth-2, +.pop-over .popup-container-depth-3, +.pop-over .popup-container-depth-4, +.pop-over .popup-container-depth-5, +.pop-over .popup-container-depth-6 { + transform: none !important; + margin-left: 0 !important; + padding-left: 0 !important; +} + +/* Ensure buttons don’t reserve left space; align to flow */ +.pop-over .content form.swimlane-color-popup .primary.confirm, +.pop-over .content form.swimlane-color-popup .negate.wide.right, +.pop-over .content .swimlane-height-popup .primary.confirm, +.pop-over .content .swimlane-height-popup .negate.wide.right { + float: none; + margin-left: 0; } .pop-over .content-container .content.no-height { - height: 2.5vh; -} -.pop-over .quiet { -/* padding: 6px 6px 4px;*/ + height: 0; + overflow: hidden; + padding: 0; + margin: 0; + visibility: hidden; } .pop-over.search-over { background: #f0f0f0; @@ -104,7 +403,7 @@ .pop-over .at-form .at-error, .pop-over .at-form .at-result { padding: 8px 12px; - margin: -8px -10px 10px; + margin: 0 0 10px 0; } .pop-over .at-form .at-error { background: #ef9a9a; @@ -148,7 +447,7 @@ font-weight: 700; padding: 1.5px 10px; position: relative; - margin: 0 -10px; + margin: 0; text-decoration: none; overflow: hidden; line-height: 33px; @@ -307,12 +606,12 @@ margin: 48px 0px 0px 0px; } .pop-over .content-container { - width: 1000%; + width: 100%; height: 100%; max-height: 100%; } .pop-over .content-container .content { - width: calc(10% - 20px); + width: calc(100% - 20px); height: calc(100% - 20px); padding: 10px; } @@ -334,21 +633,21 @@ margin: 0px 0px; } .pop-over .popup-container-depth-1 { - transform: translateX(-10%); + transform: none !important; } .pop-over .popup-container-depth-2 { - transform: translateX(-20%); + transform: none !important; } .pop-over .popup-container-depth-3 { - transform: translateX(-30%); + transform: none !important; } .pop-over .popup-container-depth-4 { - transform: translateX(-40%); + transform: none !important; } .pop-over .popup-container-depth-5 { - transform: translateX(-50%); + transform: none !important; } .pop-over .popup-container-depth-6 { - transform: translateX(-60%); + transform: none !important; } } diff --git a/client/components/main/popup.tpl.jade b/client/components/main/popup.tpl.jade index 1add6033e..bcc5756e4 100644 --- a/client/components/main/popup.tpl.jade +++ b/client/components/main/popup.tpl.jade @@ -2,13 +2,13 @@ class="{{#unless title}}miniprofile{{/unless}}" class=currentBoard.colorClass class="{{#unless title}}no-title{{/unless}}" - style="left:{{offset.left}}px; top:{{offset.top}}px;") + style="left:{{offset.left}}px; top:{{offset.top}}px;{{#if offset.maxHeight}} max-height:{{offset.maxHeight}}px;{{/if}}") .header a.back-btn.js-back-view(class="{{#unless hasPopupParent}}is-hidden{{/unless}}") - i.fa.fa-chevron-left + | ◀️ span.header-title= title a.close-btn.js-close-pop-over - i.fa.fa-times-thin + | ❌ .content-wrapper //- We display the all stack of popup content next to each other and move diff --git a/client/components/migrationProgress.css b/client/components/migrationProgress.css new file mode 100644 index 000000000..f3b9a45d4 --- /dev/null +++ b/client/components/migrationProgress.css @@ -0,0 +1,269 @@ +/* Migration Progress Styles */ +.migration-progress-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.7); + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + backdrop-filter: blur(2px); +} + +.migration-progress-modal { + background: white; + border-radius: 8px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); + max-width: 500px; + width: 90%; + max-height: 80vh; + overflow: hidden; + animation: migrationModalSlideIn 0.3s ease-out; +} + +@keyframes migrationModalSlideIn { + from { + opacity: 0; + transform: translateY(-20px) scale(0.95); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.migration-progress-header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 20px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.migration-progress-title { + margin: 0; + font-size: 18px; + font-weight: 600; +} + +.migration-progress-close { + cursor: pointer; + font-size: 16px; + opacity: 0.8; + transition: opacity 0.2s ease; +} + +.migration-progress-close:hover { + opacity: 1; +} + +.migration-progress-content { + padding: 30px; +} + +.migration-progress-overall { + margin-bottom: 25px; +} + +.migration-progress-overall-label { + font-weight: 600; + color: #333; + margin-bottom: 8px; + font-size: 14px; +} + +.migration-progress-overall-bar { + background: #e9ecef; + border-radius: 10px; + height: 12px; + overflow: hidden; + margin-bottom: 5px; +} + +.migration-progress-overall-fill { + background: linear-gradient(90deg, #28a745, #20c997); + height: 100%; + border-radius: 10px; + transition: width 0.3s ease; + position: relative; +} + +.migration-progress-overall-fill::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); + animation: migrationProgressShimmer 2s infinite; +} + +@keyframes migrationProgressShimmer { + 0% { transform: translateX(-100%); } + 100% { transform: translateX(100%); } +} + +.migration-progress-overall-percentage { + text-align: right; + font-size: 12px; + color: #666; + font-weight: 600; +} + +.migration-progress-current-step { + margin-bottom: 25px; +} + +.migration-progress-step-label { + font-weight: 600; + color: #333; + margin-bottom: 8px; + font-size: 14px; +} + +.migration-progress-step-bar { + background: #e9ecef; + border-radius: 8px; + height: 8px; + overflow: hidden; + margin-bottom: 5px; +} + +.migration-progress-step-fill { + background: linear-gradient(90deg, #007bff, #0056b3); + height: 100%; + border-radius: 8px; + transition: width 0.3s ease; +} + +.migration-progress-step-percentage { + text-align: right; + font-size: 12px; + color: #666; + font-weight: 600; +} + +.migration-progress-status { + margin-bottom: 20px; + padding: 15px; + background: #f8f9fa; + border-radius: 6px; + border-left: 4px solid #007bff; +} + +.migration-progress-status-label { + font-weight: 600; + color: #333; + margin-bottom: 5px; + font-size: 13px; +} + +.migration-progress-status-text { + color: #555; + font-size: 14px; + line-height: 1.4; +} + +.migration-progress-details { + margin-bottom: 20px; + padding: 12px; + background: #e3f2fd; + border-radius: 6px; + border-left: 4px solid #2196f3; +} + +.migration-progress-details-label { + font-weight: 600; + color: #1976d2; + margin-bottom: 5px; + font-size: 13px; +} + +.migration-progress-details-text { + color: #1565c0; + font-size: 13px; + line-height: 1.4; +} + +.migration-progress-footer { + padding: 20px 30px; + background: #f8f9fa; + border-top: 1px solid #e9ecef; +} + +.migration-progress-note { + text-align: center; + color: #666; + font-size: 13px; + font-style: italic; +} + +/* Responsive design */ +@media (max-width: 600px) { + .migration-progress-modal { + width: 95%; + margin: 20px; + } + + .migration-progress-content { + padding: 20px; + } + + .migration-progress-header { + padding: 15px; + } + + .migration-progress-title { + font-size: 16px; + } +} + +/* Dark mode support */ +@media (prefers-color-scheme: dark) { + .migration-progress-modal { + background: #2d3748; + color: #e2e8f0; + } + + .migration-progress-overall-label, + .migration-progress-step-label, + .migration-progress-status-label { + color: #e2e8f0; + } + + .migration-progress-status { + background: #4a5568; + border-left-color: #63b3ed; + } + + .migration-progress-status-text { + color: #cbd5e0; + } + + .migration-progress-details { + background: #2b6cb0; + border-left-color: #4299e1; + } + + .migration-progress-details-label { + color: #bee3f8; + } + + .migration-progress-details-text { + color: #90cdf4; + } + + .migration-progress-footer { + background: #4a5568; + border-top-color: #718096; + } + + .migration-progress-note { + color: #a0aec0; + } +} \ No newline at end of file diff --git a/client/components/migrationProgress.jade b/client/components/migrationProgress.jade new file mode 100644 index 000000000..250e20920 --- /dev/null +++ b/client/components/migrationProgress.jade @@ -0,0 +1,43 @@ +template(name="migrationProgress") + if isMigrating + .migration-progress-overlay + .migration-progress-modal + .migration-progress-header + h3.migration-progress-title + | 🔄 Board Migration in Progress + .migration-progress-close.js-close-migration-progress + | ❌ + + .migration-progress-content + .migration-progress-overall + .migration-progress-overall-label + | Overall Progress: {{currentStep}} of {{totalSteps}} steps + .migration-progress-overall-bar + .migration-progress-overall-fill(style="{{progressBarStyle}}") + .migration-progress-overall-percentage + | {{overallProgress}}% + + .migration-progress-current-step + .migration-progress-step-label + | Current Step: {{stepNameFormatted}} + .migration-progress-step-bar + .migration-progress-step-fill(style="{{stepProgressBarStyle}}") + .migration-progress-step-percentage + | {{stepProgress}}% + + .migration-progress-status + .migration-progress-status-label + | Status: + .migration-progress-status-text + | {{stepStatus}} + + if stepDetailsFormatted + .migration-progress-details + .migration-progress-details-label + | Details: + .migration-progress-details-text + | {{stepDetailsFormatted}} + + .migration-progress-footer + .migration-progress-note + | Please wait while we migrate your board to the latest structure... \ No newline at end of file diff --git a/client/components/migrationProgress.js b/client/components/migrationProgress.js new file mode 100644 index 000000000..7c4064d39 --- /dev/null +++ b/client/components/migrationProgress.js @@ -0,0 +1,212 @@ +/** + * Migration Progress Component + * Displays detailed progress for comprehensive board migration + */ + +import { ReactiveVar } from 'meteor/reactive-var'; +import { ReactiveCache } from '/imports/reactiveCache'; + +// Reactive variables for migration progress +export const migrationProgress = new ReactiveVar(0); +export const migrationStatus = new ReactiveVar(''); +export const migrationStepName = new ReactiveVar(''); +export const migrationStepProgress = new ReactiveVar(0); +export const migrationStepStatus = new ReactiveVar(''); +export const migrationStepDetails = new ReactiveVar(null); +export const migrationCurrentStep = new ReactiveVar(0); +export const migrationTotalSteps = new ReactiveVar(0); +export const isMigrating = new ReactiveVar(false); + +class MigrationProgressManager { + constructor() { + this.progressHistory = []; + } + + /** + * Update migration progress + */ + updateProgress(progressData) { + const { + overallProgress, + currentStep, + totalSteps, + stepName, + stepProgress, + stepStatus, + stepDetails, + boardId + } = progressData; + + // Update reactive variables + migrationProgress.set(overallProgress); + migrationCurrentStep.set(currentStep); + migrationTotalSteps.set(totalSteps); + migrationStepName.set(stepName); + migrationStepProgress.set(stepProgress); + migrationStepStatus.set(stepStatus); + migrationStepDetails.set(stepDetails); + + // Store in history + this.progressHistory.push({ + timestamp: new Date(), + ...progressData + }); + + // Update overall status + migrationStatus.set(`${stepName}: ${stepStatus}`); + } + + /** + * Start migration + */ + startMigration() { + isMigrating.set(true); + migrationProgress.set(0); + migrationStatus.set('Starting migration...'); + migrationStepName.set(''); + migrationStepProgress.set(0); + migrationStepStatus.set(''); + migrationStepDetails.set(null); + migrationCurrentStep.set(0); + migrationTotalSteps.set(0); + this.progressHistory = []; + } + + /** + * Complete migration + */ + completeMigration() { + isMigrating.set(false); + migrationProgress.set(100); + migrationStatus.set('Migration completed successfully!'); + + // Clear step details after a delay + setTimeout(() => { + migrationStepName.set(''); + migrationStepProgress.set(0); + migrationStepStatus.set(''); + migrationStepDetails.set(null); + migrationCurrentStep.set(0); + migrationTotalSteps.set(0); + }, 3000); + } + + /** + * Fail migration + */ + failMigration(error) { + isMigrating.set(false); + migrationStatus.set(`Migration failed: ${error.message || error}`); + migrationStepStatus.set('Error occurred'); + } + + /** + * Get progress history + */ + getProgressHistory() { + return this.progressHistory; + } + + /** + * Clear progress + */ + clearProgress() { + isMigrating.set(false); + migrationProgress.set(0); + migrationStatus.set(''); + migrationStepName.set(''); + migrationStepProgress.set(0); + migrationStepStatus.set(''); + migrationStepDetails.set(null); + migrationCurrentStep.set(0); + migrationTotalSteps.set(0); + this.progressHistory = []; + } +} + +// Export singleton instance +export const migrationProgressManager = new MigrationProgressManager(); + +// Template helpers +Template.migrationProgress.helpers({ + isMigrating() { + return isMigrating.get(); + }, + + overallProgress() { + return migrationProgress.get(); + }, + + overallStatus() { + return migrationStatus.get(); + }, + + currentStep() { + return migrationCurrentStep.get(); + }, + + totalSteps() { + return migrationTotalSteps.get(); + }, + + stepName() { + return migrationStepName.get(); + }, + + stepProgress() { + return migrationStepProgress.get(); + }, + + stepStatus() { + return migrationStepStatus.get(); + }, + + stepDetails() { + return migrationStepDetails.get(); + }, + + progressBarStyle() { + const progress = migrationProgress.get(); + return `width: ${progress}%`; + }, + + stepProgressBarStyle() { + const progress = migrationStepProgress.get(); + return `width: ${progress}%`; + }, + + stepNameFormatted() { + const stepName = migrationStepName.get(); + if (!stepName) return ''; + + // Convert snake_case to Title Case + return stepName + .split('_') + .map(word => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); + }, + + stepDetailsFormatted() { + const details = migrationStepDetails.get(); + if (!details) return ''; + + const formatted = []; + for (const [key, value] of Object.entries(details)) { + const formattedKey = key + .split(/(?=[A-Z])/) + .join(' ') + .toLowerCase() + .replace(/^\w/, c => c.toUpperCase()); + formatted.push(`${formattedKey}: ${value}`); + } + + return formatted.join(', '); + } +}); + +// Template events +Template.migrationProgress.events({ + 'click .js-close-migration-progress'() { + migrationProgressManager.clearProgress(); + } +}); \ No newline at end of file diff --git a/client/components/notifications/notifications.jade b/client/components/notifications/notifications.jade index c58db37ca..75391f349 100644 --- a/client/components/notifications/notifications.jade +++ b/client/components/notifications/notifications.jade @@ -1,5 +1,6 @@ template(name='notifications') #notifications.board-header-btns.right - a.notifications-drawer-toggle.fa.fa-bell(class="{{#if $gt unreadNotifications 0}}alert{{/if}}" title="{{_ 'notifications'}}") + a.notifications-drawer-toggle(class="{{#if $gt unreadNotifications 0}}alert{{/if}}" title="{{_ 'notifications'}}") + | 🔔 if $.Session.get 'showNotificationsDrawer' +notificationsDrawer(unreadNotifications=unreadNotifications) diff --git a/client/components/rules/actions/boardActions.jade b/client/components/rules/actions/boardActions.jade index 0a09d98e8..6f63635fa 100644 --- a/client/components/rules/actions/boardActions.jade +++ b/client/components/rules/actions/boardActions.jade @@ -10,7 +10,7 @@ template(name="boardActions") div.trigger-text | {{_'r-its-list'}} div.trigger-button.js-add-gen-move-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -38,7 +38,7 @@ template(name="boardActions") div.trigger-dropdown input(id="swimlaneName",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-spec-move-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -49,7 +49,7 @@ template(name="boardActions") div.trigger-text | {{_'r-card'}} div.trigger-button.js-add-arch-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -58,7 +58,7 @@ template(name="boardActions") div.trigger-dropdown input(id="swimlane-name",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-swimlane-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -75,7 +75,7 @@ template(name="boardActions") div.trigger-dropdown input(id="swimlane-name2",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-create-card-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -99,7 +99,7 @@ template(name="boardActions") div.trigger-dropdown input(id="swimlaneName-link",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-link-card-action.js-goto-rules - i.fa.fa-plus + | ➕ diff --git a/client/components/rules/actions/cardActions.jade b/client/components/rules/actions/cardActions.jade index aa31ca6da..baaf883af 100644 --- a/client/components/rules/actions/cardActions.jade +++ b/client/components/rules/actions/cardActions.jade @@ -16,7 +16,7 @@ template(name="cardActions") div.trigger-text | {{_'r-to-current-datetime'}} div.trigger-button.js-set-date-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -30,7 +30,7 @@ template(name="cardActions") option(value="endAt") {{_'r-df-end-at'}} option(value="receivedAt") {{_'r-df-received-at'}} div.trigger-button.js-remove-datevalue-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -46,7 +46,7 @@ template(name="cardActions") option(value="#{_id}") = name div.trigger-button.js-add-label-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -59,14 +59,14 @@ template(name="cardActions") div.trigger-dropdown input(id="member-name",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-member-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content div.trigger-text | {{_'r-remove-all'}} div.trigger-button.js-add-removeall-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -77,12 +77,12 @@ template(name="cardActions") class="card-details-{{cardColorButton}}") | {{_ cardColorButtonText }} div.trigger-button.js-set-color-action.js-goto-rules - i.fa.fa-plus + | ➕ template(name="setCardActionsColorPopup") form.edit-label .palette-colors: each colors span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") if(isSelected color) - i.fa.fa-check + | ✅ button.primary.confirm.js-submit {{_ 'save'}} diff --git a/client/components/rules/actions/checklistActions.jade b/client/components/rules/actions/checklistActions.jade index 0c2e04f13..399483ec8 100644 --- a/client/components/rules/actions/checklistActions.jade +++ b/client/components/rules/actions/checklistActions.jade @@ -10,7 +10,7 @@ template(name="checklistActions") div.trigger-dropdown input(id="checklist-name",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-checklist-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -23,7 +23,7 @@ template(name="checklistActions") div.trigger-dropdown input(id="checklist-name2",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-checkall-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item @@ -41,7 +41,7 @@ template(name="checklistActions") div.trigger-dropdown input(id="checklist-name3",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-check-item-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -54,7 +54,7 @@ template(name="checklistActions") div.trigger-dropdown input(id="checklist-items",type=text,placeholder="{{_'r-items-list'}}") div.trigger-button.js-add-checklist-items-action.js-goto-rules - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content diff --git a/client/components/rules/actions/mailActions.jade b/client/components/rules/actions/mailActions.jade index 7be78c751..098629e10 100644 --- a/client/components/rules/actions/mailActions.jade +++ b/client/components/rules/actions/mailActions.jade @@ -8,4 +8,4 @@ template(name="mailActions") input(id="email-subject",type=text,placeholder="{{_'r-subject'}}") textarea(id="email-msg") div.trigger-button.trigger-button-email.js-mail-action.js-goto-rules - i.fa.fa-plus + | ➕ diff --git a/client/components/rules/ruleDetails.jade b/client/components/rules/ruleDetails.jade index 57d52006d..d0c10e559 100644 --- a/client/components/rules/ruleDetails.jade +++ b/client/components/rules/ruleDetails.jade @@ -1,7 +1,7 @@ template(name="ruleDetails") .rules h2 - i.fa.fa-magic + | ✨ | {{_ 'r-rule-details' }} .triggers-content .triggers-body @@ -20,5 +20,5 @@ template(name="ruleDetails") = action div.rules-back button.js-goback - i.fa.fa-chevron-left + | ◀️ | {{_ 'back'}} diff --git a/client/components/rules/rulesActions.jade b/client/components/rules/rulesActions.jade index 26deae185..bcc5d7ff0 100644 --- a/client/components/rules/rulesActions.jade +++ b/client/components/rules/rulesActions.jade @@ -1,19 +1,19 @@ template(name="rulesActions") h2 - i.fa.fa-magic + | ✨ | {{_ 'r-rule' }} "#{data.ruleName.get}" - {{_ 'r-add-action'}} .triggers-content .triggers-body .triggers-side-menu ul li.active.js-set-board-actions - i.fa.fa-columns + | 📊 li.js-set-card-actions - i.fa.fa-sticky-note + | 📝 li.js-set-checklist-actions - i.fa.fa-check + | ✅ li.js-set-mail-actions - i.fa.fa-at + | @ .triggers-main-body if ($eq currentActions.get 'board') +boardActions(ruleName=data.ruleName triggerVar=data.triggerVar) @@ -25,5 +25,5 @@ template(name="rulesActions") +mailActions(ruleName=data.ruleName triggerVar=data.triggerVar) div.rules-back button.js-goback - i.fa.fa-chevron-left + | ◀️ | {{_ 'back'}} diff --git a/client/components/rules/rulesList.jade b/client/components/rules/rulesList.jade index 3c59a19f3..f13255cb1 100644 --- a/client/components/rules/rulesList.jade +++ b/client/components/rules/rulesList.jade @@ -1,7 +1,7 @@ template(name="rulesList") .rules h2 - i.fa.fa-magic + | ✨ | {{_ 'r-board-rules' }} ul.rules-list @@ -11,27 +11,27 @@ template(name="rulesList") = title div.rules-btns-group button.js-goto-details - i.fa.fa-eye + | 👁️ | {{_ 'r-view-rule'}} if currentUser.isAdmin button.js-delete-rule - i.fa.fa-trash-o + | 🗑️ | {{_ 'r-delete-rule'}} else if currentUser.isBoardAdmin button.js-delete-rule - i.fa.fa-trash-o + | 🗑️ | {{_ 'r-delete-rule'}} else li.no-items-message {{_ 'r-no-rules' }} if currentUser.isAdmin div.rules-add button.js-goto-trigger - i.fa.fa-plus + | ➕ | {{_ 'r-add-rule'}} input(type=text,placeholder="{{_ 'r-new-rule-name' }}",id="ruleTitle") else if currentUser.isBoardAdmin div.rules-add button.js-goto-trigger - i.fa.fa-plus + | ➕ | {{_ 'r-add-rule'}} input(type=text,placeholder="{{_ 'r-new-rule-name' }}",id="ruleTitle") diff --git a/client/components/rules/rulesTriggers.jade b/client/components/rules/rulesTriggers.jade index 03cf0e8fe..e34c1dfb5 100644 --- a/client/components/rules/rulesTriggers.jade +++ b/client/components/rules/rulesTriggers.jade @@ -1,17 +1,17 @@ template(name="rulesTriggers") h2 - i.fa.fa-magic + | ✨ | {{_ 'r-rule' }} "#{data.ruleName.get}" - {{_ 'r-add-trigger'}} .triggers-content .triggers-body .triggers-side-menu ul li.active.js-set-board-triggers - i.fa.fa-columns + | 📊 li.js-set-card-triggers - i.fa.fa-sticky-note + | 📝 li.js-set-checklist-triggers - i.fa.fa-check + | ✅ .triggers-main-body if showBoardTrigger.get +boardTriggers @@ -21,5 +21,5 @@ template(name="rulesTriggers") +checklistTriggers div.rules-back button.js-goback - i.fa.fa-chevron-left + | ◀️ | {{_ 'back'}} diff --git a/client/components/rules/triggers/boardTriggers.jade b/client/components/rules/triggers/boardTriggers.jade index cf13f8594..d9d2c4e17 100644 --- a/client/components/rules/triggers/boardTriggers.jade +++ b/client/components/rules/triggers/boardTriggers.jade @@ -4,7 +4,7 @@ template(name="boardTriggers") div.trigger-text | {{_'r-when-a-card'}} div.trigger-inline-button.js-open-card-title-popup - i.fa.fa-filter + | 🔍 div.trigger-text | {{_'r-is'}} div.trigger-text @@ -18,39 +18,39 @@ template(name="boardTriggers") div.trigger-dropdown input(id="create-swimlane-name",type=text,placeholder="{{_'r-swimlane-name'}}") div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-create-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item#trigger-three div.trigger-content div.trigger-text | {{_'r-when-a-card'}} div.trigger-inline-button.js-open-card-title-popup - i.fa.fa-filter + | 🔍 div.trigger-text | {{_'r-is-moved'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-moved-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item#trigger-four div.trigger-content div.trigger-text | {{_'r-when-a-card'}} div.trigger-inline-button.js-open-card-title-popup - i.fa.fa-filter + | 🔍 div.trigger-text | {{_'r-is'}} div.trigger-dropdown @@ -66,21 +66,21 @@ template(name="boardTriggers") div.trigger-dropdown input(id="create-swimlane-name-2",type=text,placeholder="{{_'r-swimlane-name'}}") div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-moved-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item#trigger-five div.trigger-content div.trigger-text | {{_'r-when-a-card'}} div.trigger-inline-button.js-open-card-title-popup - i.fa.fa-filter + | 🔍 div.trigger-text | {{_'r-is'}} div.trigger-dropdown @@ -88,14 +88,14 @@ template(name="boardTriggers") option(value="archived") {{_'r-archived'}} option(value="unarchived") {{_'r-unarchived'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-arch-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content diff --git a/client/components/rules/triggers/cardTriggers.jade b/client/components/rules/triggers/cardTriggers.jade index ba4276a51..60c024452 100644 --- a/client/components/rules/triggers/cardTriggers.jade +++ b/client/components/rules/triggers/cardTriggers.jade @@ -10,14 +10,14 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-label-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -37,14 +37,14 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-label-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -57,14 +57,14 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-member-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item @@ -82,14 +82,14 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-member-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -104,11 +104,11 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-attachment-trigger.js-goto-action - i.fa.fa-plus + | ➕ diff --git a/client/components/rules/triggers/checklistTriggers.jade b/client/components/rules/triggers/checklistTriggers.jade index 841ec6f7d..b6c16f1de 100644 --- a/client/components/rules/triggers/checklistTriggers.jade +++ b/client/components/rules/triggers/checklistTriggers.jade @@ -10,14 +10,14 @@ template(name="checklistTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-check-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item @@ -35,14 +35,14 @@ template(name="checklistTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-check-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -53,14 +53,14 @@ template(name="checklistTriggers") option(value="completed") {{_'r-completed'}} option(value="uncompleted") {{_'r-made-incomplete'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-comp-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -75,14 +75,14 @@ template(name="checklistTriggers") option(value="completed") {{_'r-completed'}} option(value="uncompleted") {{_'r-made-incomplete'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-comp-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -93,14 +93,14 @@ template(name="checklistTriggers") option(value="checked") {{_'r-checked'}} option(value="unchecked") {{_'r-unchecked'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-check-item-trigger.js-goto-action - i.fa.fa-plus + | ➕ div.trigger-item div.trigger-content @@ -115,11 +115,11 @@ template(name="checklistTriggers") option(value="checked") {{_'r-checked'}} option(value="unchecked") {{_'r-unchecked'}} div.trigger-button.trigger-button-person.js-show-user-field - i.fa.fa-user + | 👤 div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-check-item-trigger.js-goto-action - i.fa.fa-plus + | ➕ diff --git a/client/components/settings/adminReports.jade b/client/components/settings/adminReports.jade index 1d6e35b16..e474ee465 100644 --- a/client/components/settings/adminReports.jade +++ b/client/components/settings/adminReports.jade @@ -8,27 +8,27 @@ template(name="adminReports") ul li a.js-report-broken(data-id="report-broken") - i.fa.fa-chain-broken + | 🔗 | {{_ 'broken-cards'}} li a.js-report-files(data-id="report-files") - i.fa.fa-paperclip + | 📎 | {{_ 'filesReportTitle'}} li a.js-report-rules(data-id="report-rules") - i.fa.fa-magic + | ✨ | {{_ 'rulesReportTitle'}} li a.js-report-boards(data-id="report-boards") - i.fa.fa-magic + | ✨ | {{_ 'boardsReportTitle'}} li a.js-report-cards(data-id="report-cards") - i.fa.fa-magic + | ✨ | {{_ 'cardsReportTitle'}} .main-body diff --git a/client/components/settings/adminReports.js b/client/components/settings/adminReports.js index 61d327298..23a438347 100644 --- a/client/components/settings/adminReports.js +++ b/client/components/settings/adminReports.js @@ -112,7 +112,7 @@ class AdminReport extends BlazeComponent { } resultsCount() { - return this.collection.find().countDocuments(); + return this.collection.find().count(); } fileSize(size) { diff --git a/client/components/settings/attachmentSettings.jade b/client/components/settings/attachmentSettings.jade index 1a8ce40e2..669f84131 100644 --- a/client/components/settings/attachmentSettings.jade +++ b/client/components/settings/attachmentSettings.jade @@ -1,33 +1,74 @@ template(name="attachmentSettings") - .setting-content.attachment-settings-content - unless currentUser.isAdmin - | {{_ 'error-notAuthorized'}} - else - .content-body - .side-menu - ul - li - a.js-attachment-storage-settings(data-id="storage-settings") - i.fa.fa-cog - | {{_ 'attachment-storage-settings'}} - li - a.js-attachment-migration(data-id="attachment-migration") - i.fa.fa-arrow-right - | {{_ 'attachment-migration'}} - li - a.js-attachment-monitoring(data-id="attachment-monitoring") - i.fa.fa-chart-line - | {{_ 'attachment-monitoring'}} + ul#attachment-setting.setting-detail + li + h3 {{_ 'attachment-storage-configuration'}} + .form-group + label {{_ 'writable-path'}} + input.wekan-form-control#filesystem-path(type="text" value="{{filesystemPath}}" readonly) + small.form-text.text-muted {{_ 'filesystem-path-description'}} + + .form-group + label {{_ 'attachments-path'}} + input.wekan-form-control#attachments-path(type="text" value="{{attachmentsPath}}" readonly) + small.form-text.text-muted {{_ 'attachments-path-description'}} + + .form-group + label {{_ 'avatars-path'}} + input.wekan-form-control#avatars-path(type="text" value="{{avatarsPath}}" readonly) + small.form-text.text-muted {{_ 'avatars-path-description'}} - .main-body - if loading.get - +spinner - else if showStorageSettings.get - +storageSettings - else if showMigration.get - +attachmentMigration - else if showMonitoring.get - +attachmentMonitoring + li + h3 {{_ 'mongodb-gridfs-storage'}} + .form-group + label {{_ 'gridfs-enabled'}} + input.wekan-form-control#gridfs-enabled(type="checkbox" checked="{{gridfsEnabled}}" disabled) + small.form-text.text-muted {{_ 'gridfs-enabled-description'}} + + li + h3 {{_ 's3-minio-storage'}} + .form-group + label {{_ 's3-enabled'}} + input.wekan-form-control#s3-enabled(type="checkbox" checked="{{s3Enabled}}" disabled) + small.form-text.text-muted {{_ 's3-enabled-description'}} + + .form-group + label {{_ 's3-endpoint'}} + input.wekan-form-control#s3-endpoint(type="text" value="{{s3Endpoint}}" readonly) + small.form-text.text-muted {{_ 's3-endpoint-description'}} + + .form-group + label {{_ 's3-bucket'}} + input.wekan-form-control#s3-bucket(type="text" value="{{s3Bucket}}" readonly) + small.form-text.text-muted {{_ 's3-bucket-description'}} + + .form-group + label {{_ 's3-region'}} + input.wekan-form-control#s3-region(type="text" value="{{s3Region}}" readonly) + small.form-text.text-muted {{_ 's3-region-description'}} + + .form-group + label {{_ 's3-access-key'}} + input.wekan-form-control#s3-access-key(type="text" placeholder="{{_ 's3-access-key-placeholder'}}" readonly) + small.form-text.text-muted {{_ 's3-access-key-description'}} + + .form-group + label {{_ 's3-secret-key'}} + input.wekan-form-control#s3-secret-key(type="password" placeholder="{{_ 's3-secret-key-placeholder'}}") + small.form-text.text-muted {{_ 's3-secret-key-description'}} + + .form-group + label {{_ 's3-ssl-enabled'}} + input.wekan-form-control#s3-ssl-enabled(type="checkbox" checked="{{s3SslEnabled}}" disabled) + small.form-text.text-muted {{_ 's3-ssl-enabled-description'}} + + .form-group + label {{_ 's3-port'}} + input.wekan-form-control#s3-port(type="number" value="{{s3Port}}" readonly) + small.form-text.text-muted {{_ 's3-port-description'}} + + .form-group + button.js-test-s3-connection.btn.btn-secondary {{_ 'test-s3-connection'}} + button.js-save-s3-settings.btn.btn-primary {{_ 'save-s3-settings'}} template(name="storageSettings") .storage-settings diff --git a/client/components/settings/attachmentSettings.js b/client/components/settings/attachmentSettings.js deleted file mode 100644 index e1becc191..000000000 --- a/client/components/settings/attachmentSettings.js +++ /dev/null @@ -1,464 +0,0 @@ -import { ReactiveCache } from '/imports/reactiveCache'; -import { TAPi18n } from '/imports/i18n'; -import { Meteor } from 'meteor/meteor'; -import { Session } from 'meteor/session'; -import { Tracker } from 'meteor/tracker'; -import { ReactiveVar } from 'meteor/reactive-var'; -import { BlazeComponent } from 'meteor/peerlibrary:blaze-components'; -import { Chart } from 'chart.js'; - -// Global reactive variables for attachment settings -const attachmentSettings = { - loading: new ReactiveVar(false), - showStorageSettings: new ReactiveVar(false), - showMigration: new ReactiveVar(false), - showMonitoring: new ReactiveVar(false), - - // Storage configuration - filesystemPath: new ReactiveVar(''), - attachmentsPath: new ReactiveVar(''), - avatarsPath: new ReactiveVar(''), - gridfsEnabled: new ReactiveVar(false), - s3Enabled: new ReactiveVar(false), - s3Endpoint: new ReactiveVar(''), - s3Bucket: new ReactiveVar(''), - s3Region: new ReactiveVar(''), - s3SslEnabled: new ReactiveVar(false), - s3Port: new ReactiveVar(443), - - // Migration settings - migrationBatchSize: new ReactiveVar(10), - migrationDelayMs: new ReactiveVar(1000), - migrationCpuThreshold: new ReactiveVar(70), - migrationProgress: new ReactiveVar(0), - migrationStatus: new ReactiveVar('idle'), - migrationLog: new ReactiveVar(''), - - // Monitoring data - totalAttachments: new ReactiveVar(0), - filesystemAttachments: new ReactiveVar(0), - gridfsAttachments: new ReactiveVar(0), - s3Attachments: new ReactiveVar(0), - totalSize: new ReactiveVar(0), - filesystemSize: new ReactiveVar(0), - gridfsSize: new ReactiveVar(0), - s3Size: new ReactiveVar(0), - - // Migration state - isMigrationRunning: new ReactiveVar(false), - isMigrationPaused: new ReactiveVar(false), - migrationQueue: new ReactiveVar([]), - currentMigration: new ReactiveVar(null) -}; - -// Main attachment settings component -BlazeComponent.extendComponent({ - onCreated() { - this.loading = attachmentSettings.loading; - this.showStorageSettings = attachmentSettings.showStorageSettings; - this.showMigration = attachmentSettings.showMigration; - this.showMonitoring = attachmentSettings.showMonitoring; - - // Load initial data - this.loadStorageConfiguration(); - this.loadMigrationSettings(); - this.loadMonitoringData(); - }, - - events() { - return [ - { - 'click a.js-attachment-storage-settings': this.switchToStorageSettings, - 'click a.js-attachment-migration': this.switchToMigration, - 'click a.js-attachment-monitoring': this.switchToMonitoring, - } - ]; - }, - - switchToStorageSettings(event) { - this.switchMenu(event, 'storage-settings'); - this.showStorageSettings.set(true); - this.showMigration.set(false); - this.showMonitoring.set(false); - }, - - switchToMigration(event) { - this.switchMenu(event, 'attachment-migration'); - this.showStorageSettings.set(false); - this.showMigration.set(true); - this.showMonitoring.set(false); - }, - - switchToMonitoring(event) { - this.switchMenu(event, 'attachment-monitoring'); - this.showStorageSettings.set(false); - this.showMigration.set(false); - this.showMonitoring.set(true); - }, - - switchMenu(event, targetId) { - const target = $(event.target); - if (!target.hasClass('active')) { - this.loading.set(true); - - $('.side-menu li.active').removeClass('active'); - target.parent().addClass('active'); - - // Load data based on target - if (targetId === 'storage-settings') { - this.loadStorageConfiguration(); - } else if (targetId === 'attachment-migration') { - this.loadMigrationSettings(); - } else if (targetId === 'attachment-monitoring') { - this.loadMonitoringData(); - } - - this.loading.set(false); - } - }, - - loadStorageConfiguration() { - Meteor.call('getAttachmentStorageConfiguration', (error, result) => { - if (!error && result) { - attachmentSettings.filesystemPath.set(result.filesystemPath || ''); - attachmentSettings.attachmentsPath.set(result.attachmentsPath || ''); - attachmentSettings.avatarsPath.set(result.avatarsPath || ''); - attachmentSettings.gridfsEnabled.set(result.gridfsEnabled || false); - attachmentSettings.s3Enabled.set(result.s3Enabled || false); - attachmentSettings.s3Endpoint.set(result.s3Endpoint || ''); - attachmentSettings.s3Bucket.set(result.s3Bucket || ''); - attachmentSettings.s3Region.set(result.s3Region || ''); - attachmentSettings.s3SslEnabled.set(result.s3SslEnabled || false); - attachmentSettings.s3Port.set(result.s3Port || 443); - } - }); - }, - - loadMigrationSettings() { - Meteor.call('getAttachmentMigrationSettings', (error, result) => { - if (!error && result) { - attachmentSettings.migrationBatchSize.set(result.batchSize || 10); - attachmentSettings.migrationDelayMs.set(result.delayMs || 1000); - attachmentSettings.migrationCpuThreshold.set(result.cpuThreshold || 70); - attachmentSettings.migrationStatus.set(result.status || 'idle'); - attachmentSettings.migrationProgress.set(result.progress || 0); - } - }); - }, - - loadMonitoringData() { - Meteor.call('getAttachmentMonitoringData', (error, result) => { - if (!error && result) { - attachmentSettings.totalAttachments.set(result.totalAttachments || 0); - attachmentSettings.filesystemAttachments.set(result.filesystemAttachments || 0); - attachmentSettings.gridfsAttachments.set(result.gridfsAttachments || 0); - attachmentSettings.s3Attachments.set(result.s3Attachments || 0); - attachmentSettings.totalSize.set(result.totalSize || 0); - attachmentSettings.filesystemSize.set(result.filesystemSize || 0); - attachmentSettings.gridfsSize.set(result.gridfsSize || 0); - attachmentSettings.s3Size.set(result.s3Size || 0); - } - }); - } -}).register('attachmentSettings'); - -// Storage settings component -BlazeComponent.extendComponent({ - onCreated() { - this.filesystemPath = attachmentSettings.filesystemPath; - this.attachmentsPath = attachmentSettings.attachmentsPath; - this.avatarsPath = attachmentSettings.avatarsPath; - this.gridfsEnabled = attachmentSettings.gridfsEnabled; - this.s3Enabled = attachmentSettings.s3Enabled; - this.s3Endpoint = attachmentSettings.s3Endpoint; - this.s3Bucket = attachmentSettings.s3Bucket; - this.s3Region = attachmentSettings.s3Region; - this.s3SslEnabled = attachmentSettings.s3SslEnabled; - this.s3Port = attachmentSettings.s3Port; - }, - - events() { - return [ - { - 'click button.js-test-s3-connection': this.testS3Connection, - 'click button.js-save-s3-settings': this.saveS3Settings, - 'change input#s3-secret-key': this.updateS3SecretKey - } - ]; - }, - - testS3Connection() { - const secretKey = $('#s3-secret-key').val(); - if (!secretKey) { - alert(TAPi18n.__('s3-secret-key-required')); - return; - } - - Meteor.call('testS3Connection', { secretKey }, (error, result) => { - if (error) { - alert(TAPi18n.__('s3-connection-failed') + ': ' + error.reason); - } else { - alert(TAPi18n.__('s3-connection-success')); - } - }); - }, - - saveS3Settings() { - const secretKey = $('#s3-secret-key').val(); - if (!secretKey) { - alert(TAPi18n.__('s3-secret-key-required')); - return; - } - - Meteor.call('saveS3Settings', { secretKey }, (error, result) => { - if (error) { - alert(TAPi18n.__('s3-settings-save-failed') + ': ' + error.reason); - } else { - alert(TAPi18n.__('s3-settings-saved')); - $('#s3-secret-key').val(''); // Clear the password field - } - }); - }, - - updateS3SecretKey(event) { - // This method can be used to validate the secret key format - const secretKey = event.target.value; - // Add validation logic here if needed - } -}).register('storageSettings'); - -// Migration component -BlazeComponent.extendComponent({ - onCreated() { - this.migrationBatchSize = attachmentSettings.migrationBatchSize; - this.migrationDelayMs = attachmentSettings.migrationDelayMs; - this.migrationCpuThreshold = attachmentSettings.migrationCpuThreshold; - this.migrationProgress = attachmentSettings.migrationProgress; - this.migrationStatus = attachmentSettings.migrationStatus; - this.migrationLog = attachmentSettings.migrationLog; - this.isMigrationRunning = attachmentSettings.isMigrationRunning; - this.isMigrationPaused = attachmentSettings.isMigrationPaused; - - // Subscribe to migration updates - this.subscription = Meteor.subscribe('attachmentMigrationStatus'); - - // Set up reactive updates - this.autorun(() => { - const status = attachmentSettings.migrationStatus.get(); - if (status === 'running') { - this.isMigrationRunning.set(true); - } else { - this.isMigrationRunning.set(false); - } - }); - }, - - onDestroyed() { - if (this.subscription) { - this.subscription.stop(); - } - }, - - events() { - return [ - { - 'click button.js-migrate-all-to-filesystem': () => this.startMigration('filesystem'), - 'click button.js-migrate-all-to-gridfs': () => this.startMigration('gridfs'), - 'click button.js-migrate-all-to-s3': () => this.startMigration('s3'), - 'click button.js-pause-migration': this.pauseMigration, - 'click button.js-resume-migration': this.resumeMigration, - 'click button.js-stop-migration': this.stopMigration, - 'change input#migration-batch-size': this.updateBatchSize, - 'change input#migration-delay-ms': this.updateDelayMs, - 'change input#migration-cpu-threshold': this.updateCpuThreshold - } - ]; - }, - - startMigration(targetStorage) { - const batchSize = parseInt($('#migration-batch-size').val()) || 10; - const delayMs = parseInt($('#migration-delay-ms').val()) || 1000; - const cpuThreshold = parseInt($('#migration-cpu-threshold').val()) || 70; - - Meteor.call('startAttachmentMigration', { - targetStorage, - batchSize, - delayMs, - cpuThreshold - }, (error, result) => { - if (error) { - alert(TAPi18n.__('migration-start-failed') + ': ' + error.reason); - } else { - this.addToLog(TAPi18n.__('migration-started') + ': ' + targetStorage); - } - }); - }, - - pauseMigration() { - Meteor.call('pauseAttachmentMigration', (error, result) => { - if (error) { - alert(TAPi18n.__('migration-pause-failed') + ': ' + error.reason); - } else { - this.addToLog(TAPi18n.__('migration-paused')); - } - }); - }, - - resumeMigration() { - Meteor.call('resumeAttachmentMigration', (error, result) => { - if (error) { - alert(TAPi18n.__('migration-resume-failed') + ': ' + error.reason); - } else { - this.addToLog(TAPi18n.__('migration-resumed')); - } - }); - }, - - stopMigration() { - if (confirm(TAPi18n.__('migration-stop-confirm'))) { - Meteor.call('stopAttachmentMigration', (error, result) => { - if (error) { - alert(TAPi18n.__('migration-stop-failed') + ': ' + error.reason); - } else { - this.addToLog(TAPi18n.__('migration-stopped')); - } - }); - } - }, - - updateBatchSize(event) { - const value = parseInt(event.target.value); - if (value >= 1 && value <= 100) { - attachmentSettings.migrationBatchSize.set(value); - } - }, - - updateDelayMs(event) { - const value = parseInt(event.target.value); - if (value >= 100 && value <= 10000) { - attachmentSettings.migrationDelayMs.set(value); - } - }, - - updateCpuThreshold(event) { - const value = parseInt(event.target.value); - if (value >= 10 && value <= 90) { - attachmentSettings.migrationCpuThreshold.set(value); - } - }, - - addToLog(message) { - const timestamp = new Date().toISOString(); - const currentLog = attachmentSettings.migrationLog.get(); - const newLog = `[${timestamp}] ${message}\n${currentLog}`; - attachmentSettings.migrationLog.set(newLog); - } -}).register('attachmentMigration'); - -// Monitoring component -BlazeComponent.extendComponent({ - onCreated() { - this.totalAttachments = attachmentSettings.totalAttachments; - this.filesystemAttachments = attachmentSettings.filesystemAttachments; - this.gridfsAttachments = attachmentSettings.gridfsAttachments; - this.s3Attachments = attachmentSettings.s3Attachments; - this.totalSize = attachmentSettings.totalSize; - this.filesystemSize = attachmentSettings.filesystemSize; - this.gridfsSize = attachmentSettings.gridfsSize; - this.s3Size = attachmentSettings.s3Size; - - // Subscribe to monitoring updates - this.subscription = Meteor.subscribe('attachmentMonitoringData'); - - // Set up chart - this.autorun(() => { - this.updateChart(); - }); - }, - - onDestroyed() { - if (this.subscription) { - this.subscription.stop(); - } - }, - - events() { - return [ - { - 'click button.js-refresh-monitoring': this.refreshMonitoring, - 'click button.js-export-monitoring': this.exportMonitoring - } - ]; - }, - - refreshMonitoring() { - Meteor.call('refreshAttachmentMonitoringData', (error, result) => { - if (error) { - alert(TAPi18n.__('monitoring-refresh-failed') + ': ' + error.reason); - } - }); - }, - - exportMonitoring() { - Meteor.call('exportAttachmentMonitoringData', (error, result) => { - if (error) { - alert(TAPi18n.__('monitoring-export-failed') + ': ' + error.reason); - } else { - // Download the exported data - const blob = new Blob([JSON.stringify(result, null, 2)], { type: 'application/json' }); - const url = URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = 'wekan-attachment-monitoring.json'; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - URL.revokeObjectURL(url); - } - }); - }, - - updateChart() { - const ctx = document.getElementById('storage-distribution-chart'); - if (!ctx) return; - - const filesystemCount = this.filesystemAttachments.get(); - const gridfsCount = this.gridfsAttachments.get(); - const s3Count = this.s3Attachments.get(); - - if (this.chart) { - this.chart.destroy(); - } - - this.chart = new Chart(ctx, { - type: 'doughnut', - data: { - labels: [ - TAPi18n.__('filesystem-storage'), - TAPi18n.__('gridfs-storage'), - TAPi18n.__('s3-storage') - ], - datasets: [{ - data: [filesystemCount, gridfsCount, s3Count], - backgroundColor: [ - '#28a745', - '#007bff', - '#ffc107' - ] - }] - }, - options: { - responsive: true, - maintainAspectRatio: false, - plugins: { - legend: { - position: 'bottom' - } - } - } - }); - } -}).register('attachmentMonitoring'); - -// Export the attachment settings for use in other components -export { attachmentSettings }; diff --git a/client/components/settings/attachments.jade b/client/components/settings/attachments.jade index 31a0e219f..111bd4db8 100644 --- a/client/components/settings/attachments.jade +++ b/client/components/settings/attachments.jade @@ -8,7 +8,7 @@ template(name="attachments") ul li a.js-move-attachments(data-id="move-attachments") - i.fa.fa-arrow-right + | ➡️ | {{_ 'attachment-move'}} .main-body @@ -80,17 +80,17 @@ template(name="moveAttachment") td if $neq version.storageName "fs" button.js-move-storage-fs - i.fa.fa-arrow-right + | ➡️ | {{_ 'attachment-move-storage-fs'}} if $neq version.storageName "gridfs" if version.storageName button.js-move-storage-gridfs - i.fa.fa-arrow-right + | ➡️ | {{_ 'attachment-move-storage-gridfs'}} if $neq version.storageName "s3" if version.storageName button.js-move-storage-s3 - i.fa.fa-arrow-right + | ➡️ | {{_ 'attachment-move-storage-s3'}} diff --git a/client/components/settings/cronSettings.css b/client/components/settings/cronSettings.css new file mode 100644 index 000000000..95c0d70ff --- /dev/null +++ b/client/components/settings/cronSettings.css @@ -0,0 +1,864 @@ +/* Cron Settings Styles */ +.cron-settings-content { + min-height: 600px; +} + +.cron-migrations { + padding: 20px; +} + +.migration-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30px; + padding-bottom: 20px; + border-bottom: 2px solid #e0e0e0; +} + +.migration-header h2 { + margin: 0; + color: #333; + font-size: 24px; + font-weight: 600; +} + +.migration-header h2 i { + margin-right: 10px; + color: #667eea; +} + +.migration-controls { + display: flex; + gap: 10px; +} + +.migration-controls .btn { + padding: 8px 16px; + font-size: 14px; + border-radius: 4px; + border: none; + cursor: pointer; + transition: all 0.3s ease; +} + +.migration-controls .btn-primary { + background-color: #28a745; + color: white; +} + +.migration-controls .btn-primary:hover { + background-color: #218838; +} + +.migration-controls .btn-warning { + background-color: #ffc107; + color: #212529; +} + +.migration-controls .btn-warning:hover { + background-color: #e0a800; +} + +.migration-controls .btn-danger { + background-color: #dc3545; + color: white; +} + +.migration-controls .btn-danger:hover { + background-color: #c82333; +} + +.migration-progress { + background: #f8f9fa; + padding: 20px; + border-radius: 8px; + margin-bottom: 30px; + border-left: 4px solid #667eea; +} + +.progress-overview { + margin-bottom: 20px; +} + +.progress-bar { + width: 100%; + height: 12px; + background-color: #e0e0e0; + border-radius: 6px; + overflow: hidden; + margin-bottom: 8px; + position: relative; +} + +.progress-fill { + height: 100%; + background: linear-gradient(90deg, #667eea, #764ba2); + border-radius: 6px; + transition: width 0.3s ease; + position: relative; +} + +.progress-fill::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient( + 90deg, + transparent, + rgba(255, 255, 255, 0.4), + transparent + ); + animation: shimmer 2s infinite; +} + +@keyframes shimmer { + 0% { + transform: translateX(-100%); + } + 100% { + transform: translateX(100%); + } +} + +.progress-text { + text-align: center; + font-weight: 700; + color: #667eea; + font-size: 18px; +} + +.progress-label { + text-align: center; + color: #666; + font-size: 14px; + margin-top: 4px; +} + +.current-step { + text-align: center; + color: #333; + font-size: 16px; + font-weight: 500; + margin-bottom: 16px; +} + +.current-step i { + margin-right: 8px; + color: #667eea; +} + +.migration-status { + text-align: center; + color: #333; + font-size: 16px; + background-color: #e3f2fd; + padding: 12px 16px; + border-radius: 6px; + border: 1px solid #bbdefb; +} + +.migration-status i { + margin-right: 8px; + color: #2196f3; +} + +.migration-steps { + margin-top: 30px; +} + +.migration-steps h3 { + margin: 0 0 20px 0; + color: #333; + font-size: 20px; + font-weight: 600; +} + +.steps-list { + max-height: 400px; + overflow-y: auto; + border: 1px solid #e0e0e0; + border-radius: 8px; +} + +.migration-step { + padding: 16px 20px; + border-bottom: 1px solid #f0f0f0; + transition: all 0.3s ease; +} + +.migration-step:last-child { + border-bottom: none; +} + +.migration-step.completed { + background-color: #d4edda; + border-left: 4px solid #28a745; +} + +.migration-step.current { + background-color: #cce7ff; + border-left: 4px solid #667eea; + animation: pulse 2s infinite; +} + +@keyframes pulse { + 0% { + box-shadow: 0 0 0 0 rgba(102, 126, 234, 0.4); + } + 70% { + box-shadow: 0 0 0 10px rgba(102, 126, 234, 0); + } + 100% { + box-shadow: 0 0 0 0 rgba(102, 126, 234, 0); + } +} + +.step-header { + display: flex; + align-items: center; + margin-bottom: 8px; +} + +.step-icon { + margin-right: 12px; + font-size: 18px; + width: 24px; + text-align: center; +} + +.step-icon i.fa-check-circle { + color: #28a745; +} + +.step-icon i.fa-cog.fa-spin { + color: #667eea; +} + +.step-icon i.fa-circle-o { + color: #ccc; +} + +.step-info { + flex: 1; +} + +.step-name { + font-weight: 600; + color: #333; + font-size: 14px; + margin-bottom: 2px; +} + +.step-description { + color: #666; + font-size: 12px; + line-height: 1.3; +} + +.step-progress { + text-align: right; + min-width: 40px; +} + +.step-progress .progress-text { + font-size: 12px; + font-weight: 600; +} + +.step-progress-bar { + width: 100%; + height: 4px; + background-color: #e0e0e0; + border-radius: 2px; + overflow: hidden; + margin-top: 8px; +} + +.step-progress-bar .progress-fill { + height: 100%; + background: linear-gradient(90deg, #667eea, #764ba2); + border-radius: 2px; + transition: width 0.3s ease; +} + +/* Cron Jobs Styles */ +.cron-jobs { + padding: 20px; +} + +.jobs-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30px; + padding-bottom: 20px; + border-bottom: 2px solid #e0e0e0; +} + +.jobs-header h2 { + margin: 0; + color: #333; + font-size: 24px; + font-weight: 600; +} + +.jobs-header h2 i { + margin-right: 10px; + color: #667eea; +} + +.jobs-controls .btn { + padding: 8px 16px; + font-size: 14px; + border-radius: 4px; + border: none; + cursor: pointer; + transition: all 0.3s ease; +} + +.jobs-controls .btn-success { + background-color: #28a745; + color: white; +} + +.jobs-controls .btn-success:hover { + background-color: #218838; +} + +.jobs-list { + margin-top: 20px; +} + +.table { + width: 100%; + border-collapse: collapse; + background: white; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.table thead { + background-color: #f8f9fa; +} + +.table th, +.table td { + padding: 12px 16px; + text-align: left; + border-bottom: 1px solid #e0e0e0; +} + +.table th { + font-weight: 600; + color: #333; + font-size: 14px; +} + +.table td { + font-size: 14px; + color: #666; +} + +.status-badge { + padding: 4px 8px; + border-radius: 4px; + font-size: 12px; + font-weight: 600; + text-transform: uppercase; +} + +.status-badge.status-running { + background-color: #d4edda; + color: #155724; +} + +.status-badge.status-stopped { + background-color: #f8d7da; + color: #721c24; +} + +.status-badge.status-paused { + background-color: #fff3cd; + color: #856404; +} + +.status-badge.status-completed { + background-color: #d1ecf1; + color: #0c5460; +} + +.status-badge.status-error { + background-color: #f8d7da; + color: #721c24; +} + +.btn-group { + display: flex; + gap: 4px; +} + +.btn-group .btn { + padding: 4px 8px; + font-size: 12px; + border-radius: 3px; + border: none; + cursor: pointer; + transition: all 0.3s ease; +} + +.btn-group .btn-success { + background-color: #28a745; + color: white; +} + +.btn-group .btn-success:hover { + background-color: #218838; +} + +.btn-group .btn-warning { + background-color: #ffc107; + color: #212529; +} + +.btn-group .btn-warning:hover { + background-color: #e0a800; +} + +.btn-group .btn-danger { + background-color: #dc3545; + color: white; +} + +.btn-group .btn-danger:hover { + background-color: #c82333; +} + +/* Add Job Form Styles */ +.cron-add-job { + padding: 20px; +} + +.add-job-header { + margin-bottom: 30px; + padding-bottom: 20px; + border-bottom: 2px solid #e0e0e0; +} + +.add-job-header h2 { + margin: 0; + color: #333; + font-size: 24px; + font-weight: 600; +} + +.add-job-header h2 i { + margin-right: 10px; + color: #667eea; +} + +.add-job-form { + max-width: 600px; +} + +.form-group { + margin-bottom: 20px; +} + +.form-group label { + display: block; + margin-bottom: 8px; + font-weight: 600; + color: #333; + font-size: 14px; +} + +.form-control { + width: 100%; + padding: 10px 12px; + border: 1px solid #ddd; + border-radius: 4px; + font-size: 14px; + transition: border-color 0.3s ease; +} + +.form-control:focus { + outline: none; + border-color: #667eea; + box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2); +} + +.form-control[type="number"] { + width: 100px; +} + +.form-actions { + display: flex; + gap: 10px; + margin-top: 30px; +} + +.form-actions .btn { + padding: 10px 20px; + font-size: 14px; + border-radius: 4px; + border: none; + cursor: pointer; + transition: all 0.3s ease; +} + +.form-actions .btn-primary { + background-color: #667eea; + color: white; +} + +.form-actions .btn-primary:hover { + background-color: #5a6fd8; +} + +.form-actions .btn-default { + background-color: #6c757d; + color: white; +} + +.form-actions .btn-default:hover { + background-color: #5a6268; +} + +/* Board Operations Styles */ +.cron-board-operations { + padding: 20px; +} + +.board-operations-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30px; + padding-bottom: 20px; + border-bottom: 2px solid #e0e0e0; +} + +.board-operations-header h2 { + margin: 0; + color: #333; + font-size: 24px; + font-weight: 600; +} + +.board-operations-header h2 i { + margin-right: 10px; + color: #667eea; +} + +.board-operations-controls { + display: flex; + gap: 10px; +} + +.board-operations-controls .btn { + padding: 8px 16px; + font-size: 14px; + border-radius: 4px; + border: none; + cursor: pointer; + transition: all 0.3s ease; +} + +.board-operations-controls .btn-success { + background-color: #28a745; + color: white; +} + +.board-operations-controls .btn-success:hover { + background-color: #218838; +} + +.board-operations-controls .btn-primary { + background-color: #667eea; + color: white; +} + +.board-operations-controls .btn-primary:hover { + background-color: #5a6fd8; +} + +.board-operations-stats { + background: #f8f9fa; + padding: 20px; + border-radius: 8px; + margin-bottom: 30px; + border-left: 4px solid #667eea; +} + +.stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 20px; +} + +.stat-item { + text-align: center; +} + +.stat-value { + font-size: 32px; + font-weight: 700; + color: #667eea; + margin-bottom: 4px; +} + +.stat-label { + font-size: 14px; + color: #666; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.system-resources { + background: #f8f9fa; + padding: 20px; + border-radius: 8px; + margin-bottom: 30px; + border-left: 4px solid #28a745; +} + +.resource-item { + display: flex; + align-items: center; + margin-bottom: 15px; +} + +.resource-item:last-child { + margin-bottom: 0; +} + +.resource-label { + min-width: 120px; + font-weight: 600; + color: #333; + font-size: 14px; +} + +.resource-bar { + flex: 1; + height: 12px; + background-color: #e0e0e0; + border-radius: 6px; + overflow: hidden; + margin: 0 15px; + position: relative; +} + +.resource-fill { + height: 100%; + border-radius: 6px; + transition: width 0.3s ease; + position: relative; +} + +.resource-item:nth-child(1) .resource-fill { + background: linear-gradient(90deg, #28a745, #20c997); +} + +.resource-item:nth-child(2) .resource-fill { + background: linear-gradient(90deg, #007bff, #6f42c1); +} + +.resource-value { + min-width: 50px; + text-align: right; + font-weight: 600; + color: #333; + font-size: 14px; +} + +.board-operations-search { + margin-bottom: 30px; +} + +.search-box { + position: relative; + max-width: 400px; +} + +.search-box .form-control { + padding-right: 40px; +} + +.search-icon { + position: absolute; + right: 12px; + top: 50%; + transform: translateY(-50%); + color: #999; + font-size: 16px; +} + +.board-operations-list { + background: white; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + overflow: hidden; +} + +.operations-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px; + background: #f8f9fa; + border-bottom: 1px solid #e0e0e0; +} + +.operations-header h3 { + margin: 0; + color: #333; + font-size: 18px; + font-weight: 600; +} + +.pagination-info { + color: #666; + font-size: 14px; +} + +.operations-table { + overflow-x: auto; +} + +.operations-table .table { + margin: 0; + border: none; +} + +.operations-table .table th { + background-color: #f8f9fa; + border-bottom: 2px solid #e0e0e0; + font-weight: 600; + color: #333; + white-space: nowrap; +} + +.operations-table .table td { + vertical-align: middle; + border-bottom: 1px solid #f0f0f0; +} + +.board-id { + font-family: monospace; + font-size: 12px; + color: #666; + background: #f8f9fa; + padding: 4px 8px; + border-radius: 4px; + display: inline-block; +} + +.operation-type { + font-weight: 500; + color: #333; + text-transform: capitalize; +} + +.progress-container { + display: flex; + align-items: center; + gap: 8px; + min-width: 120px; +} + +.progress-container .progress-bar { + flex: 1; + height: 8px; + background-color: #e0e0e0; + border-radius: 4px; + overflow: hidden; +} + +.progress-container .progress-fill { + height: 100%; + background: linear-gradient(90deg, #667eea, #764ba2); + border-radius: 4px; + transition: width 0.3s ease; +} + +.progress-container .progress-text { + font-size: 12px; + font-weight: 600; + color: #667eea; + min-width: 35px; + text-align: right; +} + +.pagination { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px; + background: #f8f9fa; + border-top: 1px solid #e0e0e0; +} + +.pagination .btn { + padding: 6px 12px; + font-size: 12px; + border-radius: 4px; + border: 1px solid #ddd; + background: white; + color: #333; + cursor: pointer; + transition: all 0.3s ease; +} + +.pagination .btn:hover { + background: #f8f9fa; + border-color: #667eea; +} + +.pagination .btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.page-info { + color: #666; + font-size: 14px; +} + +/* Responsive design */ +@media (max-width: 768px) { + .migration-header, + .jobs-header { + flex-direction: column; + align-items: flex-start; + gap: 15px; + } + + .migration-controls, + .jobs-controls { + width: 100%; + justify-content: center; + } + + .table { + font-size: 12px; + } + + .table th, + .table td { + padding: 8px 12px; + } + + .btn-group { + flex-direction: column; + } + + .add-job-form { + max-width: 100%; + } +} diff --git a/client/components/settings/cronSettings.jade b/client/components/settings/cronSettings.jade new file mode 100644 index 000000000..b1b71a0d1 --- /dev/null +++ b/client/components/settings/cronSettings.jade @@ -0,0 +1,309 @@ +template(name="cronSettings") + ul#cron-setting.setting-detail + li + h3 {{_ 'cron-migrations'}} + .form-group + label {{_ 'migration-status'}} + .status-indicator + span.status-label {{_ 'status'}}: + span.status-value {{migrationStatus}} + .progress-section + .progress + .progress-bar(role="progressbar" style="width: {{migrationProgress}}%" aria-valuenow="{{migrationProgress}}" aria-valuemin="0" aria-valuemax="100") + | {{migrationProgress}}% + .progress-text + | {{migrationProgress}}% {{_ 'complete'}} + + .form-group + button.js-start-all-migrations.btn.btn-primary {{_ 'start-all-migrations'}} + button.js-pause-all-migrations.btn.btn-warning {{_ 'pause-all-migrations'}} + button.js-stop-all-migrations.btn.btn-danger {{_ 'stop-all-migrations'}} + + li + h3 {{_ 'board-operations'}} + .form-group + label {{_ 'scheduled-board-operations'}} + button.js-schedule-board-cleanup.btn.btn-primary {{_ 'schedule-board-cleanup'}} + button.js-schedule-board-archive.btn.btn-warning {{_ 'schedule-board-archive'}} + button.js-schedule-board-backup.btn.btn-info {{_ 'schedule-board-backup'}} + + li + h3 {{_ 'cron-jobs'}} + .form-group + label {{_ 'active-cron-jobs'}} + each cronJobs + .job-item + .job-info + .job-name {{name}} + .job-schedule {{schedule}} + .job-description {{description}} + .job-actions + button.js-pause-job.btn.btn-sm.btn-warning(data-job-id="{{_id}}") {{_ 'pause'}} + button.js-delete-job.btn.btn-sm.btn-danger(data-job-id="{{_id}}") {{_ 'delete'}} + .add-job-section + button.js-add-cron-job.btn.btn-success {{_ 'add-cron-job'}} + +template(name="cronMigrations") + .cron-migrations + .migration-header + h2 + | 🗄️ + | {{_ 'database-migrations'}} + .migration-controls + button.btn.btn-primary.js-start-all-migrations + | ▶️ + | {{_ 'start-all-migrations'}} + button.btn.btn-warning.js-pause-all-migrations + | ⏸️ + | {{_ 'pause-all-migrations'}} + button.btn.btn-danger.js-stop-all-migrations + | ⏹️ + | {{_ 'stop-all-migrations'}} + + .migration-progress + .progress-overview + .progress-bar + .progress-fill(style="width: {{migrationProgress}}%") + .progress-text {{migrationProgress}}% + .progress-label {{_ 'overall-progress'}} + + .current-step + | ⚙️ + | {{migrationCurrentStep}} + + .migration-status + | ℹ️ + | {{migrationStatus}} + + .migration-steps + h3 {{_ 'migration-steps'}} + .steps-list + each migrationSteps + .migration-step(class="{{#if completed}}completed{{/if}}" class="{{#if isCurrentStep}}current{{/if}}") + .step-header + .step-icon + if completed + | ✅ + else if isCurrentStep + | ⚙️ + else + | ⭕ + .step-info + .step-name {{name}} + .step-description {{description}} + .step-progress + if completed + .progress-text 100% + else if isCurrentStep + .progress-text {{progress}}% + else + .progress-text 0% + if isCurrentStep + .step-progress-bar + .progress-fill(style="width: {{progress}}%") + +template(name="cronBoardOperations") + .cron-board-operations + .board-operations-header + h2 + | 📋 + | {{_ 'board-operations'}} + .board-operations-controls + button.btn.btn-success.js-refresh-board-operations + | 🔄 + | {{_ 'refresh'}} + button.btn.btn-primary.js-start-test-operation + | ▶️ + | {{_ 'start-test-operation'}} + button.btn.btn-info.js-force-board-scan + | 🔍 + | {{_ 'force-board-scan'}} + + .board-operations-stats + .stats-grid + .stat-item + .stat-value {{operationStats.total}} + .stat-label {{_ 'total-operations'}} + .stat-item + .stat-value {{operationStats.running}} + .stat-label {{_ 'running'}} + .stat-item + .stat-value {{operationStats.completed}} + .stat-label {{_ 'completed'}} + .stat-item + .stat-value {{operationStats.error}} + .stat-label {{_ 'errors'}} + .stat-item + .stat-value {{queueStats.pending}} + .stat-label {{_ 'pending'}} + .stat-item + .stat-value {{queueStats.maxConcurrent}} + .stat-label {{_ 'max-concurrent'}} + .stat-item + .stat-value {{boardMigrationStats.unmigratedCount}} + .stat-label {{_ 'unmigrated-boards'}} + .stat-item + .stat-value {{boardMigrationStats.isScanning}} + .stat-label {{_ 'scanning-status'}} + + .system-resources + .resource-item + .resource-label {{_ 'cpu-usage'}} + .resource-bar + .resource-fill(style="width: {{systemResources.cpuUsage}}%") + .resource-value {{systemResources.cpuUsage}}% + .resource-item + .resource-label {{_ 'memory-usage'}} + .resource-bar + .resource-fill(style="width: {{systemResources.memoryUsage}}%") + .resource-value {{systemResources.memoryUsage}}% + .resource-item + .resource-label {{_ 'cpu-cores'}} + .resource-value {{systemResources.cpuCores}} + + .board-operations-search + .search-box + input.form-control.js-search-board-operations(type="text" placeholder="{{_ 'search-boards-or-operations'}}") + | 🔍.search-icon + + .board-operations-list + .operations-header + h3 {{_ 'board-operations'}} ({{pagination.total}}) + .pagination-info + | {{_ 'showing'}} {{pagination.start}} - {{pagination.end}} {{_ 'of'}} {{pagination.total}} + + .operations-table + table.table.table-striped + thead + tr + th {{_ 'board-id'}} + th {{_ 'operation-type'}} + th {{_ 'status'}} + th {{_ 'progress'}} + th {{_ 'start-time'}} + th {{_ 'duration'}} + th {{_ 'actions'}} + tbody + each boardOperations + tr + td + .board-id {{boardId}} + td + .operation-type {{operationType}} + td + span.status-badge(class="status-{{status}}") {{status}} + td + .progress-container + .progress-bar + .progress-fill(style="width: {{progress}}%") + .progress-text {{progress}}% + td {{formatDateTime startTime}} + td {{formatDuration startTime endTime}} + td + .btn-group + if isRunning + button.btn.btn-sm.btn-warning.js-pause-operation(data-operation="{{id}}") + | ⏸️ + else + button.btn.btn-sm.btn-success.js-resume-operation(data-operation="{{id}}") + | ▶️ + button.btn.btn-sm.btn-danger.js-stop-operation(data-operation="{{id}}") + | ⏹️ + button.btn.btn-sm.btn-info.js-view-details(data-operation="{{id}}") + | ℹ️ + + .pagination + if pagination.hasPrev + button.btn.btn-sm.btn-default.js-prev-page + | ◀️ + | {{_ 'previous'}} + .page-info + | {{_ 'page'}} {{pagination.page}} {{_ 'of'}} {{pagination.totalPages}} + if pagination.hasNext + button.btn.btn-sm.btn-default.js-next-page + | {{_ 'next'}} + | ▶️ + +template(name="cronJobs") + .cron-jobs + .jobs-header + h2 + | ⏰ + | {{_ 'cron-jobs'}} + .jobs-controls + button.btn.btn-success.js-refresh-jobs + | 🔄 + | {{_ 'refresh'}} + + .jobs-list + table.table.table-striped + thead + tr + th {{_ 'job-name'}} + th {{_ 'schedule'}} + th {{_ 'status'}} + th {{_ 'last-run'}} + th {{_ 'next-run'}} + th {{_ 'actions'}} + tbody + each cronJobs + tr + td {{name}} + td {{schedule}} + td + span.status-badge(class="status-{{status}}") {{status}} + td {{formatDate lastRun}} + td {{formatDate nextRun}} + td + .btn-group + if isRunning + button.btn.btn-sm.btn-warning.js-pause-job(data-job="{{name}}") + | ⏸️ + else + button.btn.btn-sm.btn-success.js-start-job(data-job="{{name}}") + | ▶️ + button.btn.btn-sm.btn-danger.js-stop-job(data-job="{{name}}") + | ⏹️ + button.btn.btn-sm.btn-danger.js-remove-job(data-job="{{name}}") + | 🗑️ + +template(name="cronAddJob") + .cron-add-job + .add-job-header + h2 + | ➕ + | {{_ 'add-cron-job'}} + + .add-job-form + form.js-add-cron-job-form + .form-group + label(for="job-name") {{_ 'job-name'}} + input.form-control#job-name(type="text" name="name" required) + + .form-group + label(for="job-description") {{_ 'job-description'}} + textarea.form-control#job-description(name="description" rows="3") + + .form-group + label(for="job-schedule") {{_ 'schedule'}} + select.form-control#job-schedule(name="schedule") + option(value="every 1 minute") {{_ 'every-1-minute'}} + option(value="every 5 minutes") {{_ 'every-5-minutes'}} + option(value="every 10 minutes") {{_ 'every-10-minutes'}} + option(value="every 30 minutes") {{_ 'every-30-minutes'}} + option(value="every 1 hour") {{_ 'every-1-hour'}} + option(value="every 6 hours") {{_ 'every-6-hours'}} + option(value="every 1 day") {{_ 'every-1-day'}} + option(value="once") {{_ 'run-once'}} + + .form-group + label(for="job-weight") {{_ 'weight'}} + input.form-control#job-weight(type="number" name="weight" value="1" min="1" max="10") + + .form-actions + button.btn.btn-primary(type="submit") + | ➕ + | {{_ 'add-job'}} + button.btn.btn-default.js-cancel-add-job + | ❌ + | {{_ 'cancel'}} diff --git a/client/components/settings/informationBody.jade b/client/components/settings/informationBody.jade index 6b0265a29..6907ac9d0 100644 --- a/client/components/settings/informationBody.jade +++ b/client/components/settings/informationBody.jade @@ -5,14 +5,14 @@ template(name='information') else .content-title span - i.fa.fa-info-circle + | ℹ️ | {{_ 'info'}} .content-body .side-menu ul li.active a.js-setting-menu(data-id="information-display") - i.fa.fa-info-circle + | ℹ️ | {{_ 'info'}} .main-body +statistics diff --git a/client/components/settings/peopleBody.css b/client/components/settings/peopleBody.css index 9a8a0a640..bb529b2d2 100644 --- a/client/components/settings/peopleBody.css +++ b/client/components/settings/peopleBody.css @@ -1,11 +1,16 @@ -.main-body { - overflow: scroll; -} +/* Scrollbar styles are now handled by settingBody.css for all admin pages */ table { color: #000; + min-width: 1200px !important; + width: max-content !important; + table-layout: auto !important; } + +/* Force People/Organizations/Teams tables to always trigger horizontal scrolling */ table td, table th { + white-space: nowrap; + min-width: 120px; border: 1px solid #d2d0d0; text-align: left; padding: 8px; @@ -66,6 +71,13 @@ table tr:nth-child(even) { left: 0 !important; display: block !important; } + +/* Make checkbox column fit content */ +table th:first-child, +table td:first-child { + width: auto; + min-width: auto; +} #divAddOrRemoveTeam { background: #008000; display: none; @@ -136,7 +148,7 @@ table tr:nth-child(even) { } .account-active-status { - width: 20px; + width: auto; text-align: center; } @@ -165,7 +177,7 @@ table tr:nth-child(even) { } .account-status { - width: 20px; + width: auto; text-align: center; } diff --git a/client/components/settings/peopleBody.jade b/client/components/settings/peopleBody.jade index afd918b8e..0aa9a4dba 100644 --- a/client/components/settings/peopleBody.jade +++ b/client/components/settings/peopleBody.jade @@ -9,34 +9,34 @@ template(name="people") +spinner else if orgSetting.get span - i.fa.fa-sitemap + | 🌐 unless isMiniScreen | {{_ 'organizations'}} input#searchOrgInput(placeholder="{{_ 'search'}}") button#searchOrgButton - i.fa.fa-search + | 🔍 | {{_ 'search'}} .ext-box-right span {{#unless isMiniScreen}}{{_ 'org-number'}}{{/unless}} #{orgNumber} else if teamSetting.get span - i.fa.fa-users + | 👥 unless isMiniScreen | {{_ 'teams'}} input#searchTeamInput(placeholder="{{_ 'search'}}") button#searchTeamButton - i.fa.fa-search + | 🔍 | {{_ 'search'}} .ext-box-right span {{#unless isMiniScreen}}{{_ 'team-number'}}{{/unless}} #{teamNumber} else if peopleSetting.get span - i.fa.fa-user + | 👤 unless isMiniScreen | {{_ 'people'}} input#searchInput(placeholder="{{_ 'search'}}") button#searchButton - i.fa.fa-search + | 🔍 | {{_ 'search'}} .divLockedUsersFilter .flex-container @@ -46,18 +46,19 @@ template(name="people") option(value="locked") {{_ 'admin-people-filter-locked'}} option(value="active") {{_ 'admin-people-filter-active'}} option(value="inactive") {{_ 'admin-people-filter-inactive'}} + option(value="admin") Admin button#unlockAllUsers.unlock-all-btn - i.fa.fa-unlock + | 🔓 | {{_ 'accounts-lockout-unlock-all'}} .ext-box-right span {{#unless isMiniScreen}}{{_ 'people-number'}}{{/unless}} #{peopleNumber} .divAddOrRemoveTeam#divAddOrRemoveTeam button#addOrRemoveTeam - i.fa.fa-edit + | ✏️ | {{_ 'add'}} / {{_ 'delete'}} {{_ 'teams'}} else if lockedUsersSetting.get span - i.fa.fa-lock.text-red + span.text-red 🔒 unless isMiniScreen | {{_ 'accounts-lockout-locked-users'}} @@ -66,19 +67,19 @@ template(name="people") ul li.active a.js-org-menu(data-id="org-setting") - i.fa.fa-sitemap + | 🌐 | {{_ 'organizations'}} li a.js-team-menu(data-id="team-setting") - i.fa.fa-users + | 👥 | {{_ 'teams'}} li a.js-people-menu(data-id="people-setting") - i.fa.fa-user + | 👤 | {{_ 'people'}} li a.js-locked-users-menu(data-id="locked-users-setting") - i.fa.fa-lock.text-red + span.text-red 🔒 | {{_ 'accounts-lockout-locked-users'}} .main-body if loading.get @@ -100,7 +101,6 @@ template(name="orgGeneral") th {{_ 'displayName'}} th {{_ 'description'}} th {{_ 'shortName'}} - th {{_ 'autoAddUsersWithDomainName'}} th {{_ 'website'}} th {{_ 'createdAt'}} th {{_ 'active'}} @@ -140,16 +140,9 @@ template(name="peopleGeneral") th {{_ 'admin-people-active-status'}} th {{_ 'username'}} th {{_ 'fullname'}} - th {{_ 'initials'}} th {{_ 'admin'}} th {{_ 'email'}} - th {{_ 'verified'}} th {{_ 'createdAt'}} - th {{_ 'active'}} - th {{_ 'authentication-method'}} - th {{_ 'import-usernames'}} - th {{_ 'organizations'}} - th {{_ 'teams'}} th +newUserRow tbody @@ -163,17 +156,17 @@ template(name="selectAllUser") template(name="newOrgRow") a.new-org - i.fa.fa-plus-square + | ➕ | {{_ 'new'}} template(name="newTeamRow") a.new-team - i.fa.fa-plus-square + | ➕ | {{_ 'new'}} template(name="newUserRow") a.new-user - i.fa.fa-plus-square + | ➕ | {{_ 'new'}} template(name="orgRow") @@ -190,10 +183,6 @@ template(name="orgRow") td {{ orgData.orgShortName }} else td {{ orgData.orgShortName }} - if orgData.orgIsActive - td {{ orgData.orgAutoAddUsersWithDomainName }} - else - td {{ orgData.orgAutoAddUsersWithDomainName }} if orgData.orgIsActive td {{ orgData.orgWebsite }} else @@ -209,10 +198,10 @@ template(name="orgRow") | {{_ 'no'}} td a.edit-org - i.fa.fa-edit + | ✏️ | {{_ 'edit'}} a.more-settings-org - i.fa.fa-ellipsis-h + | ⋯ template(name="teamRow") tr @@ -243,10 +232,10 @@ template(name="teamRow") | {{_ 'no'}} td a.edit-team - i.fa.fa-edit + | ✏️ | {{_ 'edit'}} a.more-settings-team - i.fa.fa-ellipsis-h + | ⋯ template(name="peopleRow") tr @@ -258,14 +247,14 @@ template(name="peopleRow") input.selectUserChkBox(type="checkbox", id="{{userData._id}}") td.account-status if isUserLocked - i.fa.fa-lock.text-red.js-toggle-lock-status(data-user-id=userData._id, data-is-locked="true", title="{{_ 'accounts-lockout-click-to-unlock'}}") + span.text-red.js-toggle-lock-status(data-user-id=userData._id, data-is-locked="true", title="{{_ 'accounts-lockout-click-to-unlock'}}") 🔒 else - i.fa.fa-unlock.text-green.js-toggle-lock-status(data-user-id=userData._id, data-is-locked="false", title="{{_ 'accounts-lockout-user-unlocked'}}") + span.text-green.js-toggle-lock-status(data-user-id=userData._id, data-is-locked="false", title="{{_ 'accounts-lockout-user-unlocked'}}") 🔓 td.account-active-status if userData.loginDisabled - i.fa.fa-ban.text-red.js-toggle-active-status(data-user-id=userData._id, data-is-active="false", title="{{_ 'admin-people-user-inactive'}}") + span.text-red.js-toggle-active-status(data-user-id=userData._id, data-is-active="false", title="{{_ 'admin-people-user-inactive'}}") 🚫 else - i.fa.fa-check-circle.text-green.js-toggle-active-status(data-user-id=userData._id, data-is-active="true", title="{{_ 'admin-people-user-active'}}") + span.text-green.js-toggle-active-status(data-user-id=userData._id, data-is-active="true", title="{{_ 'admin-people-user-active'}}") ✅ if userData.loginDisabled td.username {{ userData.username }} else if isUserLocked @@ -276,10 +265,6 @@ template(name="peopleRow") td {{ userData.profile.fullname }} else td {{ userData.profile.fullname }} - if userData.loginDisabled - td {{ userData.profile.initials }} - else - td {{ userData.profile.initials }} if userData.loginDisabled td if userData.isAdmin @@ -296,49 +281,16 @@ template(name="peopleRow") td {{ userData.emails.[0].address }} else td {{ userData.emails.[0].address }} - if userData.loginDisabled - td - if userData.emails.[0].verified - | {{_ 'yes'}} - else - | {{_ 'no'}} - else - td - if userData.emails.[0].verified - | {{_ 'yes'}} - else - | {{_ 'no'}} if userData.loginDisabled td {{ moment userData.createdAt 'LLL' }} else td {{ moment userData.createdAt 'LLL' }} - td - if userData.loginDisabled - | {{_ 'no'}} - else - | {{_ 'yes'}} - if userData.loginDisabled - td {{_ userData.authenticationMethod }} - else - td {{_ userData.authenticationMethod }} - if userData.loginDisabled - td {{ userData.importUsernamesString }} - else - td {{ userData.importUsernamesString }} - if userData.loginDisabled - td {{ userData.orgsUserBelongs }} - else - td {{ userData.orgsUserBelongs }} - if userData.loginDisabled - td {{ userData.teamsUserBelongs }} - else - td {{ userData.teamsUserBelongs }} td a.edit-user - i.fa.fa-edit + | ✏️ | {{_ 'edit'}} a.more-settings-user - i.fa.fa-ellipsis-h + | ⋯ template(name="editOrgPopup") form @@ -448,8 +400,8 @@ template(name="editUserPopup") option(value="{{value}}") {{_ value}} label | {{_ 'organizations'}} - i.fa.fa-plus-square#addUserOrg - i.fa.fa-minus-square#removeUserOrg + span#addUserOrg ➕ + span#removeUserOrg ➖ select.js-orgs#jsOrgs option(value="-1") {{_ 'organizations'}} : each value in orgsDatas @@ -458,8 +410,8 @@ template(name="editUserPopup") input#jsUserOrgIdsInPut.js-userOrgIds.hide(type="hidden" value=user.orgIdsUserBelongs) label | {{_ 'teams'}} - i.fa.fa-plus-square#addUserTeam - i.fa.fa-minus-square#removeUserTeam + span#addUserTeam ➕ + span#removeUserTeam ➖ select.js-teams#jsTeams option(value="-1") {{_ 'teams'}} : each value in teamsDatas @@ -591,8 +543,8 @@ template(name="newUserPopup") option(value="{{value}}") {{_ value}} label | {{_ 'organizations'}} - i.fa.fa-plus-square#addUserOrgNewUser - i.fa.fa-minus-square#removeUserOrgNewUser + span#addUserOrgNewUser ➕ + span#removeUserOrgNewUser ➖ select.js-orgsNewUser#jsOrgsNewUser option(value="-1") {{_ 'organizations'}} : each value in orgsDatas @@ -601,8 +553,8 @@ template(name="newUserPopup") input#jsUserOrgIdsInPutNewUser.js-userOrgIdsNewUser.hide(type="text" value=user.orgIdsUserBelongs) label | {{_ 'teams'}} - i.fa.fa-plus-square#addUserTeamNewUser - i.fa.fa-minus-square#removeUserTeamNewUser + span#addUserTeamNewUser ➕ + span#removeUserTeamNewUser ➖ select.js-teamsNewUser#jsTeamsNewUser option(value="-1") {{_ 'teams'}} : each value in teamsDatas @@ -636,7 +588,7 @@ template(name="settingsOrgPopup") // to impersonate organization? // li // a.impersonate-org - // i.fa.fa-user + // | 👤 // | {{_ 'impersonate-org'}} // // @@ -659,7 +611,7 @@ template(name="settingsUserPopup") ul.pop-over-list li a.impersonate-user - i.fa.fa-user + | 👤 | {{_ 'impersonate-user'}} br hr diff --git a/client/components/settings/peopleBody.js b/client/components/settings/peopleBody.js index 622155d61..9abaf7ff3 100644 --- a/client/components/settings/peopleBody.js +++ b/client/components/settings/peopleBody.js @@ -172,6 +172,10 @@ BlazeComponent.extendComponent({ // Show only inactive users (loginDisabled is true) query['loginDisabled'] = true; break; + case 'admin': + // Show only admin users (isAdmin is true) + query['isAdmin'] = true; + break; case 'all': default: // Show all users, no additional filter diff --git a/client/components/settings/settingBody.css b/client/components/settings/settingBody.css index 04ffb46ba..765baa77c 100644 --- a/client/components/settings/settingBody.css +++ b/client/components/settings/settingBody.css @@ -59,7 +59,79 @@ -ms-user-select: text; user-select: text; max-height: 100%; - overflow: auto; + overflow-x: scroll !important; + overflow-y: scroll !important; + scrollbar-gutter: stable; + /* Force horizontal scrollbar to always be visible */ + min-width: 100%; + width: 100%; +} + +/* Ensure scrollbars are always visible with proper styling for all admin pages */ +.setting-content .content-body .main-body::-webkit-scrollbar { + width: 12px; + height: 12px; + display: block !important; + visibility: visible !important; +} + +.setting-content .content-body .main-body::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 6px; + display: block !important; + visibility: visible !important; +} + +.setting-content .content-body .main-body::-webkit-scrollbar-thumb { + background: #888; + border-radius: 6px; + display: block !important; + visibility: visible !important; +} + +.setting-content .content-body .main-body::-webkit-scrollbar-thumb:hover { + background: #555; +} + +.setting-content .content-body .main-body::-webkit-scrollbar-corner { + background: #f1f1f1; +} + +/* Ensure tables and content are wide enough to trigger horizontal scrolling */ +.setting-content .content-body .main-body table { + min-width: 1200px !important; + width: max-content !important; + table-layout: auto !important; +} + +/* Force tables to always trigger horizontal scrolling */ +.setting-content .content-body .main-body table td, +.setting-content .content-body .main-body table th { + white-space: nowrap; + min-width: 120px; +} + +/* Ensure there's enough content to trigger vertical scrolling */ +.setting-content .content-body .main-body { + min-height: calc(100vh - 200px); + padding-bottom: 50px; +} + +/* Force horizontal scrollbar to always be visible at bottom */ +.setting-content .content-body .main-body { + position: relative; +} + +/* Add invisible content to force horizontal scrolling when needed */ +.setting-content .content-body .main-body::after { + content: ''; + display: block; + width: 100vw; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + pointer-events: none; } .setting-content .content-body .main-body ul li { padding: 0.5rem 0.5rem; diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade index deefd98fc..9101e18f7 100644 --- a/client/components/settings/settingBody.jade +++ b/client/components/settings/settingBody.jade @@ -3,71 +3,226 @@ template(name="setting") unless currentUser.isAdmin | {{_ 'error-notAuthorized'}} else - .content-title - i.fa.fa-cog - span {{_ 'settings'}} + .content-title.ext-box + if isGeneralSetting + span + | 🔑 + | {{_ 'registration'}} + else if isEmailSetting + span + | ✉️ + | {{_ 'email'}} + else if isAccountSetting + span + | 👥 + | {{_ 'accounts'}} + else if isTableVisibilityModeSetting + span + | 👁️ + | {{_ 'tableVisibilityMode'}} + else if isAnnouncementSetting + span + | 📢 + | {{_ 'admin-announcement'}} + else if isAccessibilitySetting + span + | ♿ + | {{_ 'accessibility'}} + else if isLayoutSetting + span + | 🔗 + | {{_ 'layout'}} + else if isWebhookSetting + span + | 🌐 + | {{_ 'global-webhook'}} + else if isAttachmentSettings + span + | 📎 + | {{_ 'attachments'}} + else if isCronSettings + span + | ⏰ + | {{_ 'cron'}} .content-body .side-menu ul - li.active + li(class="{{#if isGeneralSetting}}active{{/if}}") a.js-setting-menu(data-id="registration-setting") - i.fa.fa-sign-in + | 🔑 | {{_ 'registration'}} unless isSandstorm - li + li(class="{{#if isEmailSetting}}active{{/if}}") a.js-setting-menu(data-id="email-setting") - i.fa.fa-envelope + | ✉️ | {{_ 'email'}} - li + li(class="{{#if isAccountSetting}}active{{/if}}") a.js-setting-menu(data-id="account-setting") - i.fa.fa-users + | 👥 | {{_ 'accounts'}} - li + li(class="{{#if isTableVisibilityModeSetting}}active{{/if}}") a.js-setting-menu(data-id="tableVisibilityMode-setting") - i.fa.fa-eye + | 👁️ | {{_ 'tableVisibilityMode'}} - li + li(class="{{#if isAnnouncementSetting}}active{{/if}}") a.js-setting-menu(data-id="announcement-setting") - i.fa.fa-bullhorn + | 📢 | {{_ 'admin-announcement'}} - li + li(class="{{#if isAccessibilitySetting}}active{{/if}}") a.js-setting-menu(data-id="accessibility-setting") - i.fa.fa-universal-access + | ♿ | {{_ 'accessibility'}} - li + li(class="{{#if isLayoutSetting}}active{{/if}}") a.js-setting-menu(data-id="layout-setting") - i.fa.fa-object-group + | 🔗 | {{_ 'layout'}} - li + li(class="{{#if isWebhookSetting}}active{{/if}}") a.js-setting-menu(data-id="webhook-setting") - i.fa.fa-globe + | 🌐 | {{_ 'global-webhook'}} - li + li(class="{{#if isAttachmentSettings}}active{{/if}}") a.js-setting-menu(data-id="attachment-settings") - i.fa.fa-paperclip - | {{_ 'attachment-settings'}} + | 📎 + | {{_ 'attachments'}} + li(class="{{#if isCronSettings}}active{{/if}}") + a.js-setting-menu(data-id="cron-settings") + | ⏰ + | {{_ 'cron'}} .main-body - if loading.get + if isLoading +spinner - else if generalSetting.get + else if isAttachmentSettings + ul#attachment-setting.setting-detail + li + h3 {{_ 'attachment-storage-configuration'}} + .form-group + label {{_ 'writable-path'}} + input.wekan-form-control#filesystem-path(type="text" value="{{filesystemPath}}" readonly) + small.form-text.text-muted {{_ 'filesystem-path-description'}} + + .form-group + label {{_ 'attachments-path'}} + input.wekan-form-control#attachments-path(type="text" value="{{attachmentsPath}}" readonly) + small.form-text.text-muted {{_ 'attachments-path-description'}} + + .form-group + label {{_ 'avatars-path'}} + input.wekan-form-control#avatars-path(type="text" value="{{avatarsPath}}" readonly) + small.form-text.text-muted {{_ 'avatars-path-description'}} + + li + h3 {{_ 'mongodb-gridfs-storage'}} + .form-group + label {{_ 'gridfs-enabled'}} + input.wekan-form-control#gridfs-enabled(type="checkbox" checked="{{gridfsEnabled}}" disabled) + small.form-text.text-muted {{_ 'gridfs-enabled-description'}} + + li + h3 {{_ 's3-minio-storage'}} + .form-group + label {{_ 's3-enabled'}} + input.wekan-form-control#s3-enabled(type="checkbox" checked="{{s3Enabled}}" disabled) + small.form-text.text-muted {{_ 's3-enabled-description'}} + + .form-group + label {{_ 's3-endpoint'}} + input.wekan-form-control#s3-endpoint(type="text" value="{{s3Endpoint}}" readonly) + small.form-text.text-muted {{_ 's3-endpoint-description'}} + + .form-group + label {{_ 's3-bucket'}} + input.wekan-form-control#s3-bucket(type="text" value="{{s3Bucket}}" readonly) + small.form-text.text-muted {{_ 's3-bucket-description'}} + + .form-group + label {{_ 's3-region'}} + input.wekan-form-control#s3-region(type="text" value="{{s3Region}}" readonly) + small.form-text.text-muted {{_ 's3-region-description'}} + + .form-group + label {{_ 's3-access-key'}} + input.wekan-form-control#s3-access-key(type="text" placeholder="{{_ 's3-access-key-placeholder'}}" readonly) + small.form-text.text-muted {{_ 's3-access-key-description'}} + + .form-group + label {{_ 's3-secret-key'}} + input.wekan-form-control#s3-secret-key(type="password" placeholder="{{_ 's3-secret-key-placeholder'}}") + small.form-text.text-muted {{_ 's3-secret-key-description'}} + + .form-group + label {{_ 's3-ssl-enabled'}} + input.wekan-form-control#s3-ssl-enabled(type="checkbox" checked="{{s3SslEnabled}}" disabled) + small.form-text.text-muted {{_ 's3-ssl-enabled-description'}} + + .form-group + label {{_ 's3-port'}} + input.wekan-form-control#s3-port(type="number" value="{{s3Port}}" readonly) + small.form-text.text-muted {{_ 's3-port-description'}} + + .form-group + button.js-test-s3-connection.btn.btn-secondary {{_ 'test-s3-connection'}} + button.js-save-s3-settings.btn.btn-primary {{_ 'save-s3-settings'}} + else if isCronSettings + ul#cron-setting.setting-detail + li + h3 {{_ 'cron-migrations'}} + .form-group + label {{_ 'migration-status'}} + .status-indicator + span.status-label {{_ 'status'}}: + span.status-value {{migrationStatus}} + .progress-section + .progress + .progress-bar(role="progressbar" style="width: {{migrationProgress}}%" aria-valuenow="{{migrationProgress}}" aria-valuemin="0" aria-valuemax="100") + | {{migrationProgress}}% + .progress-text + | {{migrationProgress}}% {{_ 'complete'}} + + .form-group + button.js-start-all-migrations.btn.btn-primary {{_ 'start-all-migrations'}} + button.js-pause-all-migrations.btn.btn-warning {{_ 'pause-all-migrations'}} + button.js-stop-all-migrations.btn.btn-danger {{_ 'stop-all-migrations'}} + + li + h3 {{_ 'board-operations'}} + .form-group + label {{_ 'scheduled-board-operations'}} + button.js-schedule-board-cleanup.btn.btn-primary {{_ 'schedule-board-cleanup'}} + button.js-schedule-board-archive.btn.btn-warning {{_ 'schedule-board-archive'}} + button.js-schedule-board-backup.btn.btn-info {{_ 'schedule-board-backup'}} + + li + h3 {{_ 'cron-jobs'}} + .form-group + label {{_ 'active-cron-jobs'}} + each cronJobs + .job-item + .job-info + .job-name {{name}} + .job-schedule {{schedule}} + .job-description {{description}} + .job-actions + button.js-pause-job.btn.btn-sm.btn-warning(data-job-id="{{_id}}") {{_ 'pause'}} + button.js-delete-job.btn.btn-sm.btn-danger(data-job-id="{{_id}}") {{_ 'delete'}} + .add-job-section + button.js-add-cron-job.btn.btn-success {{_ 'add-cron-job'}} + else if isGeneralSetting +general - else if emailSetting.get + else if isEmailSetting unless isSandstorm +email - else if accountSetting.get + else if isAccountSetting +accountSettings - else if tableVisibilityModeSetting.get + else if isTableVisibilityModeSetting +tableVisibilityModeSettings - else if announcementSetting.get + else if isAnnouncementSetting +announcementSettings - else if accessibilitySetting.get + else if isAccessibilitySetting +accessibilitySettings - else if layoutSetting.get + else if isLayoutSetting +layoutSettings - else if webhookSetting.get + else if isWebhookSetting +webhookSettings - else if attachmentSettings.get - +attachmentSettings template(name="webhookSettings") span diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js index 566c4f99a..682479c92 100644 --- a/client/components/settings/settingBody.js +++ b/client/components/settings/settingBody.js @@ -3,11 +3,12 @@ import { TAPi18n } from '/imports/i18n'; import { ALLOWED_WAIT_SPINNERS } from '/config/const'; import LockoutSettings from '/models/lockoutSettings'; + BlazeComponent.extendComponent({ onCreated() { this.error = new ReactiveVar(''); this.loading = new ReactiveVar(false); - this.forgotPasswordSetting = new ReactiveVar(true); + this.forgotPasswordSetting = new ReactiveVar(false); this.generalSetting = new ReactiveVar(true); this.emailSetting = new ReactiveVar(false); this.accountSetting = new ReactiveVar(false); @@ -17,6 +18,7 @@ BlazeComponent.extendComponent({ this.layoutSetting = new ReactiveVar(false); this.webhookSetting = new ReactiveVar(false); this.attachmentSettings = new ReactiveVar(false); + this.cronSettings = new ReactiveVar(false); Meteor.subscribe('setting'); Meteor.subscribe('mailServer'); @@ -28,14 +30,243 @@ BlazeComponent.extendComponent({ Meteor.subscribe('lockoutSettings'); }, + setError(error) { this.error.set(error); }, + + // Template helpers moved to BlazeComponent - using different names to avoid conflicts + isGeneralSetting() { + return this.generalSetting && this.generalSetting.get(); + }, + isEmailSetting() { + return this.emailSetting && this.emailSetting.get(); + }, + isAccountSetting() { + return this.accountSetting && this.accountSetting.get(); + }, + isTableVisibilityModeSetting() { + return this.tableVisibilityModeSetting && this.tableVisibilityModeSetting.get(); + }, + isAnnouncementSetting() { + return this.announcementSetting && this.announcementSetting.get(); + }, + isAccessibilitySetting() { + return this.accessibilitySetting && this.accessibilitySetting.get(); + }, + isLayoutSetting() { + return this.layoutSetting && this.layoutSetting.get(); + }, + isWebhookSetting() { + return this.webhookSetting && this.webhookSetting.get(); + }, + isAttachmentSettings() { + return this.attachmentSettings && this.attachmentSettings.get(); + }, + isCronSettings() { + return this.cronSettings && this.cronSettings.get(); + }, + isLoading() { + return this.loading && this.loading.get(); + }, + + // Attachment settings helpers + filesystemPath() { + return process.env.WRITABLE_PATH || '/data'; + }, + + attachmentsPath() { + const writablePath = process.env.WRITABLE_PATH || '/data'; + return `${writablePath}/attachments`; + }, + + avatarsPath() { + const writablePath = process.env.WRITABLE_PATH || '/data'; + return `${writablePath}/avatars`; + }, + + gridfsEnabled() { + return process.env.GRIDFS_ENABLED === 'true'; + }, + + s3Enabled() { + return process.env.S3_ENABLED === 'true'; + }, + + s3Endpoint() { + return process.env.S3_ENDPOINT || ''; + }, + + s3Bucket() { + return process.env.S3_BUCKET || ''; + }, + + s3Region() { + return process.env.S3_REGION || ''; + }, + + s3SslEnabled() { + return process.env.S3_SSL_ENABLED === 'true'; + }, + + s3Port() { + return process.env.S3_PORT || 443; + }, + + // Cron settings helpers + migrationStatus() { + return TAPi18n.__('idle'); // Placeholder + }, + + migrationProgress() { + return 0; // Placeholder + }, + + cronJobs() { + return []; // Placeholder + }, setLoading(w) { this.loading.set(w); }, + // Event handlers for attachment settings + 'click button.js-test-s3-connection'(event) { + event.preventDefault(); + const secretKey = $('#s3-secret-key').val(); + if (!secretKey) { + alert(TAPi18n.__('s3-secret-key-required')); + return; + } + + Meteor.call('testS3Connection', { secretKey }, (error, result) => { + if (error) { + alert(TAPi18n.__('s3-connection-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('s3-connection-success')); + } + }); + }, + + 'click button.js-save-s3-settings'(event) { + event.preventDefault(); + const secretKey = $('#s3-secret-key').val(); + if (!secretKey) { + alert(TAPi18n.__('s3-secret-key-required')); + return; + } + + Meteor.call('saveS3Settings', { secretKey }, (error, result) => { + if (error) { + alert(TAPi18n.__('s3-settings-save-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('s3-settings-saved')); + $('#s3-secret-key').val(''); // Clear the password field + } + }); + }, + + // Event handlers for cron settings + 'click button.js-start-all-migrations'(event) { + event.preventDefault(); + Meteor.call('startAllMigrations', (error, result) => { + if (error) { + alert(TAPi18n.__('migration-start-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('migration-started')); + } + }); + }, + + 'click button.js-pause-all-migrations'(event) { + event.preventDefault(); + Meteor.call('pauseAllMigrations', (error, result) => { + if (error) { + alert(TAPi18n.__('migration-pause-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('migration-paused')); + } + }); + }, + + 'click button.js-stop-all-migrations'(event) { + event.preventDefault(); + if (confirm(TAPi18n.__('migration-stop-confirm'))) { + Meteor.call('stopAllMigrations', (error, result) => { + if (error) { + alert(TAPi18n.__('migration-stop-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('migration-stopped')); + } + }); + } + }, + + 'click button.js-schedule-board-cleanup'(event) { + event.preventDefault(); + Meteor.call('scheduleBoardCleanup', (error, result) => { + if (error) { + alert(TAPi18n.__('board-cleanup-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('board-cleanup-scheduled')); + } + }); + }, + + 'click button.js-schedule-board-archive'(event) { + event.preventDefault(); + Meteor.call('scheduleBoardArchive', (error, result) => { + if (error) { + alert(TAPi18n.__('board-archive-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('board-archive-scheduled')); + } + }); + }, + + 'click button.js-schedule-board-backup'(event) { + event.preventDefault(); + Meteor.call('scheduleBoardBackup', (error, result) => { + if (error) { + alert(TAPi18n.__('board-backup-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('board-backup-scheduled')); + } + }); + }, + + 'click button.js-pause-job'(event) { + event.preventDefault(); + const jobId = $(event.target).data('job-id'); + Meteor.call('pauseCronJob', jobId, (error, result) => { + if (error) { + alert(TAPi18n.__('cron-job-pause-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('cron-job-paused')); + } + }); + }, + + 'click button.js-delete-job'(event) { + event.preventDefault(); + const jobId = $(event.target).data('job-id'); + if (confirm(TAPi18n.__('cron-job-delete-confirm'))) { + Meteor.call('deleteCronJob', jobId, (error, result) => { + if (error) { + alert(TAPi18n.__('cron-job-delete-failed') + ': ' + error.reason); + } else { + alert(TAPi18n.__('cron-job-deleted')); + } + }); + } + }, + + 'click button.js-add-cron-job'(event) { + event.preventDefault(); + // Placeholder for adding a new cron job (e.g., open a modal) + alert(TAPi18n.__('add-cron-job-placeholder')); + }, + checkField(selector) { const value = $(selector).val(); if (!value || value.trim() === '') { @@ -100,22 +331,62 @@ BlazeComponent.extendComponent({ toggleDisplayAuthenticationMethod() { $('#display-authentication-method').toggleClass('is-checked'); }, + + initializeAttachmentSubMenu() { + // Set default sub-menu state for attachment settings + // This will be handled by the attachment settings component + console.log('Initializing attachment sub-menu'); + }, + + initializeCronSubMenu() { + // Set default sub-menu state for cron settings + // This will be handled by the cron settings template + console.log('Initializing cron sub-menu'); + }, switchMenu(event) { const target = $(event.target); if (!target.hasClass('active')) { $('.side-menu li.active').removeClass('active'); target.parent().addClass('active'); const targetID = target.data('id'); - this.forgotPasswordSetting.set('forgot-password-setting' === targetID); - this.generalSetting.set('registration-setting' === targetID); - this.emailSetting.set('email-setting' === targetID); - this.accountSetting.set('account-setting' === targetID); - this.announcementSetting.set('announcement-setting' === targetID); - this.accessibilitySetting.set('accessibility-setting' === targetID); - this.layoutSetting.set('layout-setting' === targetID); - this.webhookSetting.set('webhook-setting' === targetID); - this.attachmentSettings.set('attachment-settings' === targetID); - this.tableVisibilityModeSetting.set('tableVisibilityMode-setting' === targetID); + + // Reset all settings to false + this.forgotPasswordSetting.set(false); + this.generalSetting.set(false); + this.emailSetting.set(false); + this.accountSetting.set(false); + this.tableVisibilityModeSetting.set(false); + this.announcementSetting.set(false); + this.accessibilitySetting.set(false); + this.layoutSetting.set(false); + this.webhookSetting.set(false); + this.attachmentSettings.set(false); + this.cronSettings.set(false); + + // Set the selected setting to true + if (targetID === 'registration-setting') { + this.generalSetting.set(true); + } else if (targetID === 'email-setting') { + this.emailSetting.set(true); + } else if (targetID === 'account-setting') { + this.accountSetting.set(true); + } else if (targetID === 'tableVisibilityMode-setting') { + this.tableVisibilityModeSetting.set(true); + } else if (targetID === 'announcement-setting') { + this.announcementSetting.set(true); + } else if (targetID === 'accessibility-setting') { + this.accessibilitySetting.set(true); + } else if (targetID === 'layout-setting') { + this.layoutSetting.set(true); + } else if (targetID === 'webhook-setting') { + this.webhookSetting.set(true); + } else if (targetID === 'attachment-settings') { + this.attachmentSettings.set(true); + this.initializeAttachmentSubMenu(); + } else if (targetID === 'cron-settings') { + this.cronSettings.set(true); + this.initializeCronSubMenu(); + } } }, @@ -213,9 +484,6 @@ BlazeComponent.extendComponent({ const displayAuthenticationMethod = $('input[name=displayAuthenticationMethod]:checked').val() === 'true'; const defaultAuthenticationMethod = $('#defaultAuthenticationMethod').val(); - const accessibilityPageEnabled = $('input[name=accessibilityPageEnabled]:checked').val() === 'true'; - const accessibilityTitle = ($('#accessibility-title').val() || '').trim(); - const accessibilityContent = ($('#accessibility-content').val() || '').trim(); const spinnerName = ($('#spinnerName').val() || '').trim(); try { @@ -239,9 +507,6 @@ BlazeComponent.extendComponent({ oidcBtnText, mailDomainName, legalNotice, - accessibilityPageEnabled, - accessibilityTitle, - accessibilityContent, }, }); } catch (e) { @@ -453,18 +718,27 @@ BlazeComponent.extendComponent({ }, saveAccessibility() { + this.setLoading(true); const title = $('#admin-accessibility-title') .val() .trim(); const content = $('#admin-accessibility-content') .val() .trim(); - AccessibilitySettings.update(AccessibilitySettings.findOne()._id, { - $set: { - title: title, - body: content - }, - }); + + try { + AccessibilitySettings.update(AccessibilitySettings.findOne()._id, { + $set: { + title: title, + body: content + }, + }); + } catch (e) { + console.error('Error saving accessibility settings:', e); + return; + } finally { + this.setLoading(false); + } }, toggleAccessibility() { @@ -527,3 +801,4 @@ Template.selectSpinnerName.helpers({ return Template.instance().data.spinnerName === match; }, }); + diff --git a/client/components/settings/settingHeader.jade b/client/components/settings/settingHeader.jade index 41434270e..cbbb9b03b 100644 --- a/client/components/settings/settingHeader.jade +++ b/client/components/settings/settingHeader.jade @@ -5,31 +5,31 @@ template(name="settingHeaderBar") .setting-header-btns.left if currentUser a.setting-header-btn.settings(href="{{pathFor 'setting'}}") - i.fa(class="fa-cog") + | ⚙️ span {{_ 'settings'}} a.setting-header-btn.people(href="{{pathFor 'people'}}") - i.fa(class="fa-users") + | 👥 span {{_ 'people'}} a.setting-header-btn.informations(href="{{pathFor 'admin-reports'}}") - i.fa(class="fa-list") + | 📋 span {{_ 'reports'}} a.setting-header-btn.informations(href="{{pathFor 'attachments'}}") - i.fa(class="fa-paperclip") + | 📎 span {{_ 'attachments'}} a.setting-header-btn.informations(href="{{pathFor 'translation'}}") - i.fa(class="fa-font") + | 🔤 span {{_ 'translation'}} a.setting-header-btn.informations(href="{{pathFor 'information'}}") - i.fa(class="fa-info-circle") + | ℹ️ span {{_ 'info'}} else a.setting-header-btn.js-log-in( title="{{_ 'log-in'}}") - i.fa.fa-sign-in + | 🚪 span {{_ 'log-in'}} diff --git a/client/components/settings/translationBody.css b/client/components/settings/translationBody.css index 8dc613c76..856b1967a 100644 --- a/client/components/settings/translationBody.css +++ b/client/components/settings/translationBody.css @@ -1,6 +1,4 @@ -.main-body { - overflow: scroll; -} +/* Scrollbar styles are now handled by settingBody.css for all admin pages */ table { color: #000; } diff --git a/client/components/settings/translationBody.jade b/client/components/settings/translationBody.jade index 46d41d011..deb721a22 100644 --- a/client/components/settings/translationBody.jade +++ b/client/components/settings/translationBody.jade @@ -9,12 +9,12 @@ template(name="translation") +spinner else if translationSetting.get span - i.fa.fa-font + | 🔤 unless isMiniScreen | {{_ 'translation'}} input#searchTranslationInput(placeholder="{{_ 'search'}}") button#searchTranslationButton - i.fa.fa-search + | 🔍 | {{_ 'search'}} .ext-box-right span {{#unless isMiniScreen}}{{_ 'translation-number'}}{{/unless}} #{translationNumber} @@ -24,7 +24,7 @@ template(name="translation") ul li.active a.js-translation-menu(data-id="translation-setting") - i.fa.fa-font + | 🔤 | {{_ 'translation'}} .main-body if loading.get @@ -47,7 +47,7 @@ template(name="translationGeneral") template(name="newTranslationRow") a.new-translation - i.fa.fa-plus-square + | ➕ | {{_ 'new'}} template(name="translationRow") @@ -57,10 +57,10 @@ template(name="translationRow") td {{translationData.translationText}} td a.edit-translation - i.fa.fa-edit + | ✏️ | {{_ 'edit'}} a.more-settings-translation - i.fa.fa-ellipsis-h + | ⋯ template(name="editTranslationPopup") form diff --git a/client/components/sidebar/sidebar.css b/client/components/sidebar/sidebar.css index 831719f36..7867aec6d 100644 --- a/client/components/sidebar/sidebar.css +++ b/client/components/sidebar/sidebar.css @@ -48,6 +48,59 @@ display: flex; flex-direction: column; } + +/* Use checklist-style green checkboxes for all sidebar checkboxes */ +.sidebar .materialCheckBox.is-checked, +.boardCardSettingsPopup .materialCheckBox.is-checked, +.boardSubtaskSettingsPopup .materialCheckBox.is-checked { + top: -4px !important; + left: -3px !important; + width: 7px !important; + height: 15px !important; + margin-right: 6px !important; + border-top: 2px solid transparent !important; + border-left: 2px solid transparent !important; + border-bottom: 2px solid #3cb500 !important; + border-right: 2px solid #3cb500 !important; + transform: rotate(40deg) !important; + -webkit-backface-visibility: hidden !important; + backface-visibility: hidden !important; + transform-origin: 100% 100% !important; +} + +/* Card Settings 3-column grid layout */ +.card-settings-grid { + display: grid; + grid-template-columns: 1fr 1fr 2fr; + gap: 10px; + margin-bottom: 10px; +} + +.card-settings-row { + display: grid; + grid-template-columns: 1fr 1fr 2fr; + gap: 10px; + align-items: center; + padding: 5px 0; + border-bottom: 1px solid #eee; +} + +.card-settings-column { + display: flex; + align-items: center; + justify-content: center; +} + +.card-settings-column:last-child { + justify-content: flex-start; +} + +.card-settings-column h4 { + margin: 0; + font-size: 12px; + font-weight: bold; + text-align: center; +} .sidebar .sidebar-content ul.sidebar-list li > a { display: flex; height: 30px; diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index 96d4f818e..e5e90e1a5 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -7,14 +7,14 @@ template(name="sidebar") .sidebar-actions .sidebar-shortcuts a.sidebar-btn.js-shortcuts(title="{{_ 'keyboard-shortcuts' }}") - i.fa.fa-keyboard-o + | ⌨️ span {{_ 'keyboard-shortcuts' }} a.sidebar-btn.js-keyboard-shortcuts-toggle( title="{{#if isKeyboardShortcuts}}{{_ 'keyboard-shortcuts-enabled'}}{{else}}{{_ 'keyboard-shortcuts-disabled'}}{{/if}}") - i.fa(class="fa-solid fa-{{#if isKeyboardShortcuts}}check-square-o{{else}}ban{{/if}}") + | {{#if isKeyboardShortcuts}}✅{{else}}🚫{{/if}} if isAccessibilityEnabled a.sidebar-accessibility - i.fa.fa-universal-access + | ♿ span {{_ 'accessibility'}} a.sidebar-xmark.js-close-sidebar ✕ .sidebar-content.js-board-sidebar-content @@ -22,44 +22,38 @@ template(name="sidebar") // i.fa.fa-navicon unless isDefaultView h2 - a.fa.fa-chevron-left.js-back-home + a.js-back-home | ⬅️ = getViewTitle if isOpen +Template.dynamic(template=getViewTemplate) template(name='homeSidebar') - hr +membersWidget hr +labelsWidget hr ul#cards.label-text-hidden a.flex.js-toggle-minicard-label-text(title="{{_ 'hide-minicard-label-text'}}") + span {{#if hiddenMinicardLabelText}}✅{{else}}⬜{{/if}} span {{_ 'hide-minicard-label-text'}} - b   - .materialCheckBox(class="{{#if hiddenMinicardLabelText}}is-checked{{/if}}") - ul#cards.vertical-scrollbars-toggle - a.flex.js-vertical-scrollbars-toggle(title="{{_ 'enable-vertical-scrollbars'}}") - span {{_ 'enable-vertical-scrollbars'}} - b   - .materialCheckBox(class="{{#if isVerticalScrollbars}}is-checked{{/if}}") + if currentUser + ul#cards.vertical-scrollbars-toggle + a.flex.js-vertical-scrollbars-toggle(title="{{_ 'enable-vertical-scrollbars'}}") + span {{#if isVerticalScrollbars}}✅{{else}}⬜{{/if}} + span {{_ 'enable-vertical-scrollbars'}} ul#cards.show-week-of-year-toggle a.flex.js-show-week-of-year-toggle(title="{{_ 'show-week-of-year'}}") + span {{#if isShowWeekOfYear}}✅{{else}}⬜{{/if}} span {{_ 'show-week-of-year'}} - b   - .materialCheckBox(class="{{#if isShowWeekOfYear}}is-checked{{/if}}") hr unless currentUser.isNoComments h3.activity-title - i.fa.fa-comments-o + | 💬 | {{_ 'activities'}} - .material-toggle-switch(title="{{_ 'show-activities'}}") - if showActivities - input.toggle-switch(type="checkbox" id="toggleShowActivitiesBoard" checked="checked") - else - input.toggle-switch(type="checkbox" id="toggleShowActivitiesBoard") - label.toggle-label(for="toggleShowActivitiesBoard") + a.flex.js-toggle-show-activities(title="{{_ 'show-activities'}}") + span {{#if showActivities}}✅{{else}}⬜{{/if}} + span {{_ 'show-activities'}} +activities(mode="board") template(name="membersWidget") @@ -67,11 +61,11 @@ template(name="membersWidget") unless currentUser.isWorker h3 a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}") - i.board-header-btn-icon.fa.fa-cog + | ⚙️ | {{_ 'boardMenuPopup-title'}} hr h3 - i.fa.fa-users + | 👥 | {{_ 'members'}} +basicTabs(tabs=tabs) +tabContent(slug="people") @@ -83,15 +77,15 @@ template(name="membersWidget") if isSandstorm if currentUser.isBoardMember a.member.add-member.sandstorm-powerbox-request-identity(title="{{_ 'add-members'}}") - i.fa.fa-plus + | ➕ else if currentUser.isBoardAdmin a.member.add-member.js-manage-board-members(title="{{_ 'add-members'}}") - i.fa.fa-plus + | ➕ .clearfix if isInvited hr p - i.fa.fa-exclamation-circle + | ⚠️ | {{_ 'just-invited'}} button.js-member-invite-accept.primary {{_ 'accept'}} button.js-member-invite-decline {{_ 'decline'}} @@ -127,7 +121,7 @@ template(name="boardOrgGeneral") th if currentUser.isBoardAdmin a.member.orgOrTeamMember.add-member.js-manage-board-addOrg(title="{{_ 'add-members'}}") - i.addTeamFaPlus.fa.fa-plus + | ➕ .divaddfaplusminus | {{_ 'add'}} each org in currentBoard.activeOrgs @@ -148,7 +142,7 @@ template(name="boardTeamGeneral") th if currentUser.isBoardAdmin a.member.orgOrTeamMember.add-member.js-manage-board-addTeam(title="{{_ 'add-members'}}") - i.addTeamFaPlus.fa.fa-plus + | ➕ .divaddfaplusminus | {{_ 'add'}} each currentBoard.activeTeams @@ -161,7 +155,7 @@ template(name="boardChangeColorPopup") span.background-box(class="board-color-{{this}}") span {{this}} if isSelected - i.fa.fa-check + | ✅ template(name="boardChangeBackgroundImagePopup") form @@ -185,168 +179,285 @@ template(name="boardInfoOnMyBoardsPopup") unless currentSetting.hideCardCounterList div.check-div a.flex.js-field-has-cardcounterlist(class="{{#if allowsCardCounterList}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsCardCounterList}}is-checked{{/if}}") + span {{#if allowsCardCounterList}}✅{{else}}⬜{{/if}} span - i.fa.fa-sign-out + | 🚪 | {{_ 'show-card-counter-per-list'}} unless currentSetting.hideBoardMemberList div.check-div a.flex.js-field-has-boardmemberlist(class="{{#if allowsBoardMemberList}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsBoardMemberList}}is-checked{{/if}}") + span {{#if allowsBoardMemberList}}✅{{else}}⬜{{/if}} span - i.fa.fa-hourglass-start + | ⏳ | {{_ 'show-board_members-avatar'}} template(name="boardCardSettingsPopup") form.board-card-settings - h3 {{_ 'show-on-card'}}, {{_ 'show-on-minicard'}} - div.check-div - a.flex.js-field-has-receiveddate(class="{{#if allowsReceivedDate}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsReceivedDate}}is-checked{{/if}}") + .card-settings-grid + .card-settings-column + h4 {{_ 'show-on-card'}} + .card-settings-column + h4 {{_ 'show-on-minicard'}} + .card-settings-column + h4 {{_ 'description'}} + .card-settings-row + .card-settings-column + a.flex.js-field-has-receiveddate(title="{{_ 'card-received'}}" class="{{#if allowsReceivedDate}}is-checked{{/if}}") + span {{#if allowsReceivedDate}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-receiveddate(title="{{_ 'card-received'}}" class="{{#if allowsReceivedDate}}is-checked{{/if}}") + span {{#if allowsReceivedDate}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-sign-out + | 🚪 | {{_ 'card-received'}} - div.check-div - a.flex.js-field-has-startdate(class="{{#if allowsStartDate}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsStartDate}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-startdate(title="{{_ 'card-start'}}" class="{{#if allowsStartDate}}is-checked{{/if}}") + span {{#if allowsStartDate}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-startdate(title="{{_ 'card-start'}}" class="{{#if allowsStartDate}}is-checked{{/if}}") + span {{#if allowsStartDate}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-hourglass-start + | ⏳ | {{_ 'card-start'}} - div.check-div - a.flex.js-field-has-duedate(class="{{#if allowsDueDate}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsDueDate}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-duedate(title="{{_ 'card-due'}}" class="{{#if allowsDueDate}}is-checked{{/if}}") + span {{#if allowsDueDate}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-duedate(title="{{_ 'card-due'}}" class="{{#if allowsDueDate}}is-checked{{/if}}") + span {{#if allowsDueDate}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-sign-in + | 🚪 | {{_ 'card-due'}} - div.check-div - a.flex.js-field-has-enddate(class="{{#if allowsEndDate}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsEndDate}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-enddate(title="{{_ 'card-end'}}" class="{{#if allowsEndDate}}is-checked{{/if}}") + span {{#if allowsEndDate}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-enddate(title="{{_ 'card-end'}}" class="{{#if allowsEndDate}}is-checked{{/if}}") + span {{#if allowsEndDate}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-hourglass-end + | ⏰ | {{_ 'card-end'}} - div.check-div - a.flex.js-field-has-members(class="{{#if allowsMembers}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsMembers}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-members(title="{{_ 'members'}}" class="{{#if allowsMembers}}is-checked{{/if}}") + span {{#if allowsMembers}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-members(title="{{_ 'members'}}" class="{{#if allowsMembers}}is-checked{{/if}}") + span {{#if allowsMembers}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-users + | 👥 | {{_ 'members'}} - div.check-div - a.flex.js-field-has-creator(class="{{#if allowsCreator}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsCreator}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-creator(title="{{_ 'creator'}}" class="{{#if allowsCreator}}is-checked{{/if}}") + span {{#if allowsCreator}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-user + .card-settings-column + span + | 👤 | {{_ 'creator'}} - div.check-div - a.flex.js-field-has-creator-on-minicard(class="{{#if allowsCreatorOnMinicard}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsCreatorOnMinicard}}is-checked{{/if}}") + .card-settings-row + .card-settings-column span - i.fa.fa-user + .card-settings-column + a.flex.js-field-has-creator-on-minicard(title="{{_ 'creator-on-minicard'}}" class="{{#if allowsCreatorOnMinicard}}is-checked{{/if}}") + span {{#if allowsCreatorOnMinicard}}✅{{else}}⬜{{/if}} + .card-settings-column + span + | 👤 | {{_ 'creator-on-minicard'}} - div.check-div - a.flex.js-field-has-assignee(class="{{#if allowsAssignee}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsAssignee}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-assignee(title="{{_ 'assignee'}}" class="{{#if allowsAssignee}}is-checked{{/if}}") + span {{#if allowsAssignee}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-assignee(title="{{_ 'assignee'}}" class="{{#if allowsAssignee}}is-checked{{/if}}") + span {{#if allowsAssignee}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-user + | 👤 | {{_ 'assignee'}} - div.check-div - a.flex.js-field-has-assigned-by(class="{{#if allowsAssignedBy}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsAssignedBy}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-assigned-by(title="{{_ 'assigned-by'}}" class="{{#if allowsAssignedBy}}is-checked{{/if}}") + span {{#if allowsAssignedBy}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-assigned-by(title="{{_ 'assigned-by'}}" class="{{#if allowsAssignedBy}}is-checked{{/if}}") + span {{#if allowsAssignedBy}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-shopping-cart + | 🛒 | {{_ 'assigned-by'}} - div.check-div - a.flex.js-field-has-requested-by(class="{{#if allowsRequestedBy}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsRequestedBy}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-requested-by(title="{{_ 'requested-by'}}" class="{{#if allowsRequestedBy}}is-checked{{/if}}") + span {{#if allowsRequestedBy}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-requested-by(title="{{_ 'requested-by'}}" class="{{#if allowsRequestedBy}}is-checked{{/if}}") + span {{#if allowsRequestedBy}}✅{{else}}⬜{{/if}} + .card-settings-column 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}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-card-sorting-by-number(title="{{_ 'card-sorting-by-number'}}" class="{{#if allowsCardSortingByNumber}}is-checked{{/if}}") + span {{#if allowsCardSortingByNumber}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-sort + .card-settings-column + span + | 🔢 | {{_ 'card-sorting-by-number'}} - div.check-div - a.flex.js-field-has-card-sorting-by-number-on-minicard(class="{{#if allowsCardSortingByNumberOnMinicard}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsCardSortingByNumberOnMinicard}}is-checked{{/if}}") + .card-settings-row + .card-settings-column span - i.fa.fa-sort + .card-settings-column + a.flex.js-field-has-card-sorting-by-number-on-minicard(title="{{_ 'card-sorting-by-number-on-minicard'}}" class="{{#if allowsCardSortingByNumberOnMinicard}}is-checked{{/if}}") + span {{#if allowsCardSortingByNumberOnMinicard}}✅{{else}}⬜{{/if}} + .card-settings-column + span + | 🔢 | {{_ 'card-sorting-by-number-on-minicard'}} - div.check-div - a.flex.js-field-has-card-show-lists(class="{{#if allowsShowLists}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsShowLists}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-card-show-lists(title="{{_ 'card-show-lists'}}" class="{{#if allowsShowLists}}is-checked{{/if}}") + span {{#if allowsShowLists}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-list + .card-settings-column + span + | 📋 | {{_ 'card-show-lists'}} - div.check-div - a.flex.js-field-has-labels(class="{{#if allowsLabels}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsLabels}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-labels(title="{{_ 'labels'}}" class="{{#if allowsLabels}}is-checked{{/if}}") + span {{#if allowsLabels}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-labels(title="{{_ 'labels'}}" class="{{#if allowsLabels}}is-checked{{/if}}") + span {{#if allowsLabels}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-tags + | 🏷️ | {{_ 'labels'}} - div.check-div - a.flex.js-field-has-card-show-lists-on-minicard(class="{{#if allowsShowListsOnMinicard}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsShowListsOnMinicard}}is-checked{{/if}}") + .card-settings-row + .card-settings-column span - i.fa.fa-list + .card-settings-column + a.flex.js-field-has-card-show-lists-on-minicard(title="{{_ 'card-show-lists-on-minicard'}}" class="{{#if allowsShowListsOnMinicard}}is-checked{{/if}}") + span {{#if allowsShowListsOnMinicard}}✅{{else}}⬜{{/if}} + .card-settings-column + span + | 📋 | {{_ 'card-show-lists-on-minicard'}} - div.check-div - a.flex.js-field-has-card-number(class="{{#if allowsCardNumber}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsCardNumber}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-card-number(title="{{_ 'card'}} {{_ 'number'}}" class="{{#if allowsCardNumber}}is-checked{{/if}}") + span {{#if allowsCardNumber}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-card-number(title="{{_ 'card'}} {{_ 'number'}}" class="{{#if allowsCardNumber}}is-checked{{/if}}") + span {{#if allowsCardNumber}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-hashtag + | #️⃣ | {{_ 'card'}} | {{_ 'number'}} - div.check-div - a.flex.js-field-has-description-title(class="{{#if allowsDescriptionTitle}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsDescriptionTitle}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-description-title(title="{{_ 'description'}} {{_ 'title'}}" class="{{#if allowsDescriptionTitle}}is-checked{{/if}}") + span {{#if allowsDescriptionTitle}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-description-title(title="{{_ 'description'}} {{_ 'title'}}" class="{{#if allowsDescriptionTitle}}is-checked{{/if}}") + span {{#if allowsDescriptionTitle}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-align-left + | 📝 | {{_ 'description'}} | {{_ 'title'}} - div.check-div - a.flex.js-field-has-description-text(class="{{#if allowsDescriptionText}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsDescriptionText}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-description-text(title="{{_ 'description'}} {{_ 'custom-field-text'}}" class="{{#if allowsDescriptionText}}is-checked{{/if}}") + span {{#if allowsDescriptionText}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-description-text(title="{{_ 'description'}} {{_ 'custom-field-text'}}" class="{{#if allowsDescriptionText}}is-checked{{/if}}") + span {{#if allowsDescriptionText}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-align-left + | 📝 | {{_ 'description'}} | {{_ 'custom-field-text'}} - div.check-div - a.flex.js-field-has-description-text-on-minicard(class="{{#if allowsDescriptionTextOnMinicard}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsDescriptionTextOnMinicard}}is-checked{{/if}}") + .card-settings-row + .card-settings-column span - i.fa.fa-align-left + .card-settings-column + a.flex.js-field-has-description-text-on-minicard(title="{{_ 'description-on-minicard'}}" class="{{#if allowsDescriptionTextOnMinicard}}is-checked{{/if}}") + span {{#if allowsDescriptionTextOnMinicard}}✅{{else}}⬜{{/if}} + .card-settings-column + span + | 📝 | {{_ 'description-on-minicard'}} - div.check-div - a.flex.js-field-has-checklists(class="{{#if allowsChecklists}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsChecklists}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-checklists(title="{{_ 'checklists'}}" class="{{#if allowsChecklists}}is-checked{{/if}}") + span {{#if allowsChecklists}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-checklists(title="{{_ 'checklists'}}" class="{{#if allowsChecklists}}is-checked{{/if}}") + span {{#if allowsChecklists}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-check + | ✅ | {{_ 'checklists'}} - div.check-div - a.flex.js-field-has-subtasks(class="{{#if allowsSubtasks}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsSubtasks}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-subtasks(title="{{_ 'subtasks'}}" class="{{#if allowsSubtasks}}is-checked{{/if}}") + span {{#if allowsSubtasks}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-subtasks(title="{{_ 'subtasks'}}" class="{{#if allowsSubtasks}}is-checked{{/if}}") + span {{#if allowsSubtasks}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-sitemap + | 🌐 | {{_ 'subtasks'}} - div.check-div - a.flex.js-field-has-attachments(class="{{#if allowsAttachments}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsAttachments}}is-checked{{/if}}") + .card-settings-row + .card-settings-column + a.flex.js-field-has-attachments(title="{{_ 'attachments'}}" class="{{#if allowsAttachments}}is-checked{{/if}}") + span {{#if allowsAttachments}}✅{{else}}⬜{{/if}} + .card-settings-column + a.flex.js-field-has-attachments(title="{{_ 'attachments'}}" class="{{#if allowsAttachments}}is-checked{{/if}}") + span {{#if allowsAttachments}}✅{{else}}⬜{{/if}} + .card-settings-column span - i.fa.fa-paperclip + | 📎 | {{_ 'attachments'}} - div.check-div - a.flex.js-field-has-badge-attachment-on-minicard(class="{{#if allowsBadgeAttachmentOnMinicard}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsBadgeAttachmentOnMinicard}}is-checked{{/if}}") + .card-settings-row + .card-settings-column span - i.fa.fa-paperclip + .card-settings-column + a.flex.js-field-has-badge-attachment-on-minicard(title="{{_ 'badge-attachment-on-minicard'}}" class="{{#if allowsBadgeAttachmentOnMinicard}}is-checked{{/if}}") + span {{#if allowsBadgeAttachmentOnMinicard}}✅{{else}}⬜{{/if}} + .card-settings-column + span + | 📎 | {{_ 'badge-attachment-on-minicard'}} - div.check-div - a.flex.js-field-has-cover-attachment-on-minicard(class="{{#if allowsCoverAttachmentOnMinicard}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsCoverAttachmentOnMinicard}}is-checked{{/if}}") + .card-settings-row + .card-settings-column span - i.fa.fa-book - i.fa.fa-picture-o + .card-settings-column + a.flex.js-field-has-cover-attachment-on-minicard(title="{{_ 'cover-attachment-on-minicard'}}" class="{{#if allowsCoverAttachmentOnMinicard}}is-checked{{/if}}") + span {{#if allowsCoverAttachmentOnMinicard}}✅{{else}}⬜{{/if}} + .card-settings-column + span + | 📖 + | 🖼️ | {{_ 'cover-attachment-on-minicard'}} //div.check-div // a.flex.js-field-has-comments(class="{{#if allowsComments}}is-checked{{/if}}") @@ -364,27 +475,27 @@ template(name="boardCardSettingsPopup") template(name="boardSubtaskSettingsPopup") form.board-subtask-settings h3 {{_ 'show-parent-in-minicard'}} - a#prefix-with-full-path.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}") - .materialCheckBox(class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}") + a#prefix-with-full-path.flex.js-field-show-parent-in-minicard(title="{{_ 'prefix-with-full-path'}}" class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}") + span {{#if $eq presentParentTask 'prefix-with-full-path'}}✅{{else}}⬜{{/if}} span {{_ 'prefix-with-full-path'}} - a#prefix-with-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}") - .materialCheckBox(class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}") + a#prefix-with-parent.flex.js-field-show-parent-in-minicard(title="{{_ 'prefix-with-parent'}}" class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}") + span {{#if $eq presentParentTask 'prefix-with-parent'}}✅{{else}}⬜{{/if}} span {{_ 'prefix-with-parent'}} - a#subtext-with-full-path.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}") - .materialCheckBox(class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}") + a#subtext-with-full-path.flex.js-field-show-parent-in-minicard(title="{{_ 'subtext-with-full-path'}}" class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}") + span {{#if $eq presentParentTask 'subtext-with-full-path'}}✅{{else}}⬜{{/if}} span {{_ 'subtext-with-full-path'}} - a#subtext-with-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}") - .materialCheckBox(class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}") + a#subtext-with-parent.flex.js-field-show-parent-in-minicard(title="{{_ 'subtext-with-parent'}}" class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}") + span {{#if $eq presentParentTask 'subtext-with-parent'}}✅{{else}}⬜{{/if}} span {{_ 'subtext-with-parent'}} - a#no-parent.flex.js-field-show-parent-in-minicard(class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}") - .materialCheckBox(class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}") + a#no-parent.flex.js-field-show-parent-in-minicard(title="{{_ 'no-parent'}}" class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}") + span {{#if $eq presentParentTask 'no-parent'}}✅{{else}}⬜{{/if}} span {{_ 'no-parent'}} div hr div.check-div - a.flex.js-field-has-subtasks(class="{{#if allowsSubtasks}}is-checked{{/if}}") - .materialCheckBox(class="{{#if allowsSubtasks}}is-checked{{/if}}") + a.flex.js-field-has-subtasks(title="{{_ 'show-subtasks-field'}}" class="{{#if allowsSubtasks}}is-checked{{/if}}") + span {{#if allowsSubtasks}}✅{{else}}⬜{{/if}} span {{_ 'show-subtasks-field'}} label @@ -423,16 +534,21 @@ template(name="chooseBoardSource") template(name="archiveBoardPopup") p {{_ 'close-board-pop'}} button.js-confirm.negate.full(type="submit") - i.fa.fa-archive + | 📦 | {{_ 'archive'}} +template(name="deleteDuplicateListsPopup") + p {{_ 'delete-duplicate-lists-confirm'}} + button.js-confirm.negate.full(type="submit") + | 🗑️ + | {{_ 'delete'}} + template(name="outgoingWebhooksPopup") each integrations form.integration-form a.flex + span {{#unless enabled}}✅{{else}}⬜{{/unless}} span {{_ 'disable-webhook'}} - b   - .materialCheckBox(class="{{#unless enabled}}is-checked{{/unless}}") input.js-outgoing-webhooks-title(placeholder="{{_ 'webhook-title'}}" type="text" name="title" value=title) input.js-outgoing-webhooks-url(type="text" name="url" value=url) input.js-outgoing-webhooks-token(placeholder="{{_ 'webhook-token' }}" type="text" value=token name="token") @@ -459,25 +575,29 @@ template(name="boardMenuPopup") if currentUser.isBoardAdmin li a.js-open-rules-view(title="{{_ 'rules'}}") - i.fa.fa-magic + | ✨ | {{_ 'rules'}} if currentUser.isBoardAdmin li a.js-custom-fields - i.fa.fa-list-alt + | 📝 | {{_ 'custom-fields'}} li a.js-open-archives - i.fa.fa-archive + | 📦 | {{_ 'archived-items'}} if currentUser.isBoardAdmin + li + a.js-open-migrations + | 🔧 + | {{_ 'migrations'}} li a.js-change-board-color - i.fa.fa-paint-brush + | 🎨 | {{_ 'board-change-color'}} li a.js-change-background-image - i.fa.fa-picture-o + | 🖼️ | {{_ 'board-change-background-image'}} //Bug Board icons random dance https://github.com/wekan/wekan/issues/4214 //if currentUser.isBoardAdmin @@ -492,62 +612,65 @@ template(name="boardMenuPopup") if withApi li a.js-export-board - i.fa.fa-share-alt + | 📤 | {{_ 'export-board'}} if currentUser.isBoardAdmin li a.js-outgoing-webhooks - i.fa.fa-globe + | 🌐 | {{_ 'outgoing-webhooks'}} li a.js-card-settings - i.fa.fa-id-card-o + | 🃏 | {{_ 'card-settings'}} li a.js-subtask-settings - i.fa.fa-sitemap + | 🌐 | {{_ 'subtask-settings'}} unless currentBoard.isTemplatesBoard if currentUser.isBoardAdmin hr ul.pop-over-list + // li + // a.js-delete-duplicate-lists + // | 🗑️ + // | {{_ 'delete-duplicate-lists'}} li a.js-archive-board - i.fa.fa-arrow-right - i.fa.fa-archive + | ➡️📦 | {{_ 'archive-board'}} template(name="exportBoard") ul.pop-over-list li a.download-json-link(href="{{exportUrl}}", download="{{exportJsonFilename}}") - i.fa.fa-share-alt + | 📤 | {{_ 'export-board-json'}} li a(href="{{exportUrlExcel}}", download="{{exportFilenameExcel}}") - i.fa.fa-share-alt + | 📤 | {{_ 'export-board-excel'}} li a(href="{{exportCsvUrl}}", download="{{exportCsvFilename}}") - i.fa.fa-share-alt + | 📤 | {{_ 'export-board-csv'}} , li a(href="{{exportScsvUrl}}", download="{{exportCsvFilename}}") - i.fa.fa-share-alt + | 📤 | {{_ 'export-board-csv'}} ; li a(href="{{exportTsvUrl}}", download="{{exportTsvFilename}}") - i.fa.fa-share-alt + | 📤 | {{_ 'export-board-tsv'}} li a.html-export-board - i.fa.fa-archive + | 📦 | {{_ 'export-board-html'}} template(name="labelsWidget") .board-widget.board-widget-labels h3 - i.fa.fa-tags + | 🏷️ | {{_ 'labels'}} .board-widget-content each currentBoard.labels @@ -558,7 +681,7 @@ template(name="labelsWidget") = name if currentUser.isBoardAdmin a.card-label.add-label.js-add-label(title="{{_ 'label-create'}}") - i.fa.fa-plus + | ➕ template(name="memberPopup") .board-member-menu @@ -570,7 +693,7 @@ template(name="memberPopup") p.quiet @#{user.username} if isInvited p - i.fa.fa-exclamation-circle + | ⚠️ | {{_ 'not-accepted-yet'}} ul.pop-over-list @@ -632,7 +755,7 @@ template(name="removeBoardTeamPopup") template(name="addMemberPopup") .js-search-member - +EasySearch.Input(index=searchIndex) + input.js-search-member-input(type="text" placeholder="{{_ 'email-address'}}") if loading.get +spinner @@ -640,56 +763,69 @@ template(name="addMemberPopup") .warning {{_ error.get}} else ul.pop-over-list - +EasySearch.Each(index=searchIndex) + each searchResults li.item.js-member-item(class="{{#if isBoardMember}}disabled{{/if}}") a.name.js-select-member(title="{{profile.fullname}} ({{username}})") - +userAvatar(userId=__originalId) + +userAvatar(userId=_id) span.full-name = profile.fullname | ({{username}}) if isBoardMember .quiet ({{_ 'joined'}}) - +EasySearch.IfSearching(index=searchIndex) + if searching.get +spinner - +EasySearch.IfNoResults(index=searchIndex) + if noResults.get .manage-member-section p.quiet {{_ 'no-results'}} button.js-email-invite.primary.full {{_ 'email-invite'}} +template(name="addMemberPopupTest") + .js-search-member + input.js-search-member-input(type="text" placeholder="{{_ 'email-address'}}") + ul.pop-over-list + each searchResults + li.item.js-member-item + a.name.js-select-member(title="{{profile.fullname}} ({{username}})") + +userAvatar(userId=_id) + span.full-name + = profile.fullname + | ({{username}}) + button.js-email-invite.primary.full {{_ 'email-invite'}} + template(name="changePermissionsPopup") ul.pop-over-list li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-admin{{/if}}") | {{_ 'admin'}} if isAdmin - i.fa.fa-check + | ✅ span.sub-name {{_ 'admin-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-normal{{/if}}") | {{_ 'normal'}} if isNormal - i.fa.fa-check + | ✅ span.sub-name {{_ 'normal-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-no-comments{{/if}}") | {{_ 'no-comments'}} if isNoComments - i.fa.fa-check + | ✅ span.sub-name {{_ 'no-comments-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-comment-only{{/if}}") | {{_ 'comment-only'}} if isCommentOnly - i.fa.fa-check + | ✅ span.sub-name {{_ 'comment-only-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-worker{{/if}}") | {{_ 'worker'}} if isWorker - i.fa.fa-check + | ✅ span.sub-name {{_ 'worker-desc'}} if isLastAdmin hr diff --git a/client/components/sidebar/sidebar.js b/client/components/sidebar/sidebar.js index 693007021..5831e601a 100644 --- a/client/components/sidebar/sidebar.js +++ b/client/components/sidebar/sidebar.js @@ -13,6 +13,7 @@ const viewTitles = { multiselection: 'multi-selection', customFields: 'custom-fields', archives: 'archives', + migrations: 'migrations', }; BlazeComponent.extendComponent({ @@ -65,8 +66,10 @@ BlazeComponent.extendComponent({ }, reachNextPeak() { - const activitiesComponent = this.childComponents('activities')[0]; - activitiesComponent.loadNextPage(); + const activitiesChildren = this.childComponents('activities'); + if (activitiesChildren && activitiesChildren.length > 0 && activitiesChildren[0] && typeof activitiesChildren[0].loadNextPage === 'function') { + activitiesChildren[0].loadNextPage(); + } }, isTongueHidden() { @@ -193,7 +196,7 @@ BlazeComponent.extendComponent({ events() { return [ { - 'click #toggleShowActivitiesBoard'() { + 'click .js-toggle-show-activities'() { Utils.getCurrentBoard().toggleShowActivities(); }, }, @@ -201,6 +204,8 @@ BlazeComponent.extendComponent({ }, }).register('homeSidebar'); + + Template.boardInfoOnMyBoardsPopup.helpers({ hideCardCounterList() { return Utils.isMiniScreen() && Session.get('currentBoard'); @@ -267,10 +272,53 @@ Template.boardMenuPopup.events({ Sidebar.setView('archives'); Popup.back(); }, + 'click .js-open-migrations'() { + Sidebar.setView('migrations'); + Popup.back(); + }, 'click .js-change-board-color': Popup.open('boardChangeColor'), 'click .js-change-background-image': Popup.open('boardChangeBackgroundImage'), 'click .js-board-info-on-my-boards': Popup.open('boardInfoOnMyBoards'), 'click .js-change-language': Popup.open('changeLanguage'), + 'click .js-delete-duplicate-lists': Popup.afterConfirm('deleteDuplicateLists', function() { + const currentBoard = Utils.getCurrentBoard(); + if (!currentBoard) return; + + // Get all lists in the current board + const allLists = ReactiveCache.getLists({ boardId: currentBoard._id, archived: false }); + + // Group lists by title to find duplicates + const listsByTitle = {}; + allLists.forEach(list => { + if (!listsByTitle[list.title]) { + listsByTitle[list.title] = []; + } + listsByTitle[list.title].push(list); + }); + + // Find and delete duplicate lists that have no cards + let deletedCount = 0; + Object.keys(listsByTitle).forEach(title => { + const listsWithSameTitle = listsByTitle[title]; + if (listsWithSameTitle.length > 1) { + // Keep the first list, delete the rest if they have no cards + for (let i = 1; i < listsWithSameTitle.length; i++) { + const list = listsWithSameTitle[i]; + const cardsInList = ReactiveCache.getCards({ listId: list._id, archived: false }); + + if (cardsInList.length === 0) { + Lists.remove(list._id); + deletedCount++; + } + } + } + }); + + // Show notification + if (deletedCount > 0) { + // You could add a toast notification here if available + } + }), 'click .js-archive-board ': Popup.afterConfirm('archiveBoard', function() { const currentBoard = Utils.getCurrentBoard(); currentBoard.archive(); @@ -818,7 +866,11 @@ BlazeComponent.extendComponent({ }, allowsSubtasks() { - return this.currentBoard.allowsSubtasks; + // Get the current board reactively using board ID from Session + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + const result = currentBoard ? currentBoard.allowsSubtasks : false; + return result; }, allowsReceivedDate() { @@ -870,7 +922,11 @@ BlazeComponent.extendComponent({ }, presentParentTask() { - let result = this.currentBoard.presentParentTask; + // Get the current board reactively using board ID from Session + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + + let result = currentBoard ? currentBoard.presentParentTask : null; if (result === null || result === undefined) { result = 'no-parent'; } @@ -882,19 +938,11 @@ BlazeComponent.extendComponent({ { 'click .js-field-has-subtasks'(evt) { evt.preventDefault(); - this.currentBoard.allowsSubtasks = !this.currentBoard.allowsSubtasks; - this.currentBoard.setAllowsSubtasks(this.currentBoard.allowsSubtasks); - $(`.js-field-has-subtasks ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsSubtasks, - ); - $('.js-field-has-subtasks').toggleClass( - CKCLS, - this.currentBoard.allowsSubtasks, - ); + const newValue = !this.currentBoard.allowsSubtasks; + Boards.update(this.currentBoard._id, { $set: { allowsSubtasks: newValue } }); $('.js-field-deposit-board').prop( 'disabled', - !this.currentBoard.allowsSubtasks, + !newValue, ); }, 'change .js-field-deposit-board'(evt) { @@ -910,28 +958,13 @@ BlazeComponent.extendComponent({ evt.preventDefault(); }, 'click .js-field-show-parent-in-minicard'(evt) { - const value = - evt.target.id || - $(evt.target).parent()[0].id || - $(evt.target) - .parent()[0] - .parent()[0].id; - const options = [ - 'prefix-with-full-path', - 'prefix-with-parent', - 'subtext-with-full-path', - 'subtext-with-parent', - 'no-parent', - ]; - options.forEach(function(element) { - if (element !== value) { - $(`#${element} ${MCB}`).toggleClass(CKCLS, false); - $(`#${element}`).toggleClass(CKCLS, false); - } - }); - $(`#${value} ${MCB}`).toggleClass(CKCLS, true); - $(`#${value}`).toggleClass(CKCLS, true); - this.currentBoard.setPresentParentTask(value); + // Get the ID from the anchor element, not the span + const anchorElement = $(evt.target).closest('.js-field-show-parent-in-minicard')[0]; + const value = anchorElement ? anchorElement.id : null; + + if (value) { + Boards.update(this.currentBoard._id, { $set: { presentParentTask: value } }); + } evt.preventDefault(); }, }, @@ -945,115 +978,168 @@ BlazeComponent.extendComponent({ }, allowsReceivedDate() { - return this.currentBoard.allowsReceivedDate; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsReceivedDate : false; }, allowsStartDate() { - return this.currentBoard.allowsStartDate; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsStartDate : false; }, allowsDueDate() { - return this.currentBoard.allowsDueDate; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsDueDate : false; }, allowsEndDate() { - return this.currentBoard.allowsEndDate; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsEndDate : false; }, allowsSubtasks() { - return this.currentBoard.allowsSubtasks; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsSubtasks : false; }, allowsCreator() { - return this.currentBoard.allowsCreator ?? false; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? (currentBoard.allowsCreator ?? false) : false; }, allowsCreatorOnMinicard() { - return this.currentBoard.allowsCreatorOnMinicard ?? false; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? (currentBoard.allowsCreatorOnMinicard ?? false) : false; }, allowsMembers() { - return this.currentBoard.allowsMembers; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsMembers : false; }, allowsAssignee() { - return this.currentBoard.allowsAssignee; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsAssignee : false; }, allowsAssignedBy() { - return this.currentBoard.allowsAssignedBy; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsAssignedBy : false; }, allowsRequestedBy() { - return this.currentBoard.allowsRequestedBy; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsRequestedBy : false; }, allowsCardSortingByNumber() { - return this.currentBoard.allowsCardSortingByNumber; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsCardSortingByNumber : false; }, allowsShowLists() { - return this.currentBoard.allowsShowLists; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsShowLists : false; }, - allowsLabels() { - return this.currentBoard.allowsLabels; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsLabels : false; }, allowsShowListsOnMinicard() { - return this.currentBoard.allowsShowListsOnMinicard; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsShowListsOnMinicard : false; }, allowsChecklists() { - return this.currentBoard.allowsChecklists; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsChecklists : false; }, allowsAttachments() { - return this.currentBoard.allowsAttachments; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsAttachments : false; }, allowsComments() { - return this.currentBoard.allowsComments; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsComments : false; }, allowsCardNumber() { - return this.currentBoard.allowsCardNumber; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsCardNumber : false; }, allowsDescriptionTitle() { - return this.currentBoard.allowsDescriptionTitle; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsDescriptionTitle : false; }, allowsDescriptionText() { - return this.currentBoard.allowsDescriptionText; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsDescriptionText : false; }, isBoardSelected() { - return this.currentBoard.dateSettingsDefaultBoardID; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.dateSettingsDefaultBoardID : false; }, isNullBoardSelected() { - return ( - this.currentBoard.dateSettingsDefaultBoardId === null || - this.currentBoard.dateSettingsDefaultBoardId === undefined - ); + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? ( + currentBoard.dateSettingsDefaultBoardId === null || + currentBoard.dateSettingsDefaultBoardId === undefined + ) : true; }, allowsDescriptionTextOnMinicard() { - return this.currentBoard.allowsDescriptionTextOnMinicard; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsDescriptionTextOnMinicard : false; }, allowsCoverAttachmentOnMinicard() { - return this.currentBoard.allowsCoverAttachmentOnMinicard; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsCoverAttachmentOnMinicard : false; }, allowsBadgeAttachmentOnMinicard() { - return this.currentBoard.allowsBadgeAttachmentOnMinicard; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsBadgeAttachmentOnMinicard : false; }, allowsCardSortingByNumberOnMinicard() { - return this.currentBoard.allowsCardSortingByNumberOnMinicard; + const boardId = Session.get('currentBoard'); + const currentBoard = ReactiveCache.getBoard(boardId); + return currentBoard ? currentBoard.allowsCardSortingByNumberOnMinicard : false; }, boards() { @@ -1096,203 +1182,73 @@ BlazeComponent.extendComponent({ { 'click .js-field-has-receiveddate'(evt) { evt.preventDefault(); - this.currentBoard.allowsReceivedDate = !this.currentBoard - .allowsReceivedDate; - this.currentBoard.setAllowsReceivedDate( - this.currentBoard.allowsReceivedDate, - ); - $(`.js-field-has-receiveddate ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsReceivedDate, - ); - $('.js-field-has-receiveddate').toggleClass( - CKCLS, - this.currentBoard.allowsReceivedDate, - ); + const newValue = !this.currentBoard.allowsReceivedDate; + Boards.update(this.currentBoard._id, { $set: { allowsReceivedDate: newValue } }); }, 'click .js-field-has-startdate'(evt) { evt.preventDefault(); - this.currentBoard.allowsStartDate = !this.currentBoard - .allowsStartDate; - this.currentBoard.setAllowsStartDate( - this.currentBoard.allowsStartDate, - ); - $(`.js-field-has-startdate ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsStartDate, - ); - $('.js-field-has-startdate').toggleClass( - CKCLS, - this.currentBoard.allowsStartDate, - ); + const newValue = !this.currentBoard.allowsStartDate; + Boards.update(this.currentBoard._id, { $set: { allowsStartDate: newValue } }); }, 'click .js-field-has-enddate'(evt) { evt.preventDefault(); - this.currentBoard.allowsEndDate = !this.currentBoard.allowsEndDate; - this.currentBoard.setAllowsEndDate(this.currentBoard.allowsEndDate); - $(`.js-field-has-enddate ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsEndDate, - ); - $('.js-field-has-enddate').toggleClass( - CKCLS, - this.currentBoard.allowsEndDate, - ); + const newValue = !this.currentBoard.allowsEndDate; + Boards.update(this.currentBoard._id, { $set: { allowsEndDate: newValue } }); }, 'click .js-field-has-duedate'(evt) { evt.preventDefault(); - this.currentBoard.allowsDueDate = !this.currentBoard.allowsDueDate; - this.currentBoard.setAllowsDueDate(this.currentBoard.allowsDueDate); - $(`.js-field-has-duedate ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsDueDate, - ); - $('.js-field-has-duedate').toggleClass( - CKCLS, - this.currentBoard.allowsDueDate, - ); + const newValue = !this.currentBoard.allowsDueDate; + Boards.update(this.currentBoard._id, { $set: { allowsDueDate: newValue } }); }, 'click .js-field-has-subtasks'(evt) { evt.preventDefault(); - this.currentBoard.allowsSubtasks = !this.currentBoard.allowsSubtasks; - this.currentBoard.setAllowsSubtasks(this.currentBoard.allowsSubtasks); - $(`.js-field-has-subtasks ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsSubtasks, - ); - $('.js-field-has-subtasks').toggleClass( - CKCLS, - this.currentBoard.allowsSubtasks, - ); + const newValue = !this.currentBoard.allowsSubtasks; + Boards.update(this.currentBoard._id, { $set: { allowsSubtasks: newValue } }); }, 'click .js-field-has-creator'(evt) { evt.preventDefault(); - this.currentBoard.allowsCreator = !this.currentBoard.allowsCreator; - this.currentBoard.setAllowsCreator(this.currentBoard.allowsCreator); - $(`.js-field-has-creator ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsCreator, - ); - $('.js-field-has-creator').toggleClass( - CKCLS, - this.currentBoard.allowsCreator, - ); + const newValue = !this.currentBoard.allowsCreator; + Boards.update(this.currentBoard._id, { $set: { allowsCreator: newValue } }); }, 'click .js-field-has-creator-on-minicard'(evt) { evt.preventDefault(); - this.currentBoard.allowsCreatorOnMinicard = !this.currentBoard.allowsCreatorOnMinicard; - this.currentBoard.setAllowsCreatorOnMinicard(this.currentBoard.allowsCreatorOnMinicard); - $(`.js-field-has-creator-on-minicard ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsCreatorOnMinicard, - ); - $('.js-field-has-creator-on-minicard').toggleClass( - CKCLS, - this.currentBoard.allowsCreatorOnMinicard, - ); + const newValue = !this.currentBoard.allowsCreatorOnMinicard; + Boards.update(this.currentBoard._id, { $set: { allowsCreatorOnMinicard: newValue } }); }, 'click .js-field-has-members'(evt) { evt.preventDefault(); - this.currentBoard.allowsMembers = !this.currentBoard.allowsMembers; - this.currentBoard.setAllowsMembers(this.currentBoard.allowsMembers); - $(`.js-field-has-members ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsMembers, - ); - $('.js-field-has-members').toggleClass( - CKCLS, - this.currentBoard.allowsMembers, - ); + const newValue = !this.currentBoard.allowsMembers; + Boards.update(this.currentBoard._id, { $set: { allowsMembers: newValue } }); }, 'click .js-field-has-assignee'(evt) { evt.preventDefault(); - this.currentBoard.allowsAssignee = !this.currentBoard.allowsAssignee; - this.currentBoard.setAllowsAssignee(this.currentBoard.allowsAssignee); - $(`.js-field-has-assignee ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsAssignee, - ); - $('.js-field-has-assignee').toggleClass( - CKCLS, - this.currentBoard.allowsAssignee, - ); + const newValue = !this.currentBoard.allowsAssignee; + Boards.update(this.currentBoard._id, { $set: { allowsAssignee: newValue } }); }, 'click .js-field-has-assigned-by'(evt) { evt.preventDefault(); - this.currentBoard.allowsAssignedBy = !this.currentBoard - .allowsAssignedBy; - this.currentBoard.setAllowsAssignedBy( - this.currentBoard.allowsAssignedBy, - ); - $(`.js-field-has-assigned-by ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsAssignedBy, - ); - $('.js-field-has-assigned-by').toggleClass( - CKCLS, - this.currentBoard.allowsAssignedBy, - ); + const newValue = !this.currentBoard.allowsAssignedBy; + Boards.update(this.currentBoard._id, { $set: { allowsAssignedBy: newValue } }); }, 'click .js-field-has-requested-by'(evt) { evt.preventDefault(); - this.currentBoard.allowsRequestedBy = !this.currentBoard - .allowsRequestedBy; - this.currentBoard.setAllowsRequestedBy( - this.currentBoard.allowsRequestedBy, - ); - $(`.js-field-has-requested-by ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsRequestedBy, - ); - $('.js-field-has-requested-by').toggleClass( - CKCLS, - this.currentBoard.allowsRequestedBy, - ); + const newValue = !this.currentBoard.allowsRequestedBy; + Boards.update(this.currentBoard._id, { $set: { allowsRequestedBy: newValue } }); }, '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, - ); + const newValue = !this.currentBoard.allowsCardSortingByNumber; + Boards.update(this.currentBoard._id, { $set: { allowsCardSortingByNumber: newValue } }); }, 'click .js-field-has-card-show-lists'(evt) { evt.preventDefault(); - this.currentBoard.allowsShowLists = !this.currentBoard - .allowsShowLists; - this.currentBoard.setAllowsShowLists( - this.currentBoard.allowsShowLists, - ); - $(`.js-field-has-card-show-lists ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsShowLists, - ); - $('.js-field-has-card-show-lists').toggleClass( - CKCLS, - this.currentBoard.allowsShowLists, - ); + const newValue = !this.currentBoard.allowsShowLists; + Boards.update(this.currentBoard._id, { $set: { allowsShowLists: newValue } }); }, 'click .js-field-has-labels'(evt) { evt.preventDefault(); - this.currentBoard.allowsLabels = !this.currentBoard.allowsLabels; - this.currentBoard.setAllowsLabels(this.currentBoard.allowsLabels); - $(`.js-field-has-labels ${MCB}`).toggleClass( - CKCLS, - this.currentBoard.allowsLabels, - ); - $('.js-field-has-labels').toggleClass( - CKCLS, - this.currentBoard.allowsLabels, - ); + const newValue = !this.currentBoard.allowsLabels; + Boards.update(this.currentBoard._id, { $set: { allowsLabels: newValue } }); }, 'click .js-field-has-card-show-lists-on-minicard'(evt) { evt.preventDefault(); @@ -1488,19 +1444,27 @@ BlazeComponent.extendComponent({ }, }).register('boardCardSettingsPopup'); +// Use Session variables instead of global ReactiveVars +Session.setDefault('addMemberPopup.searchResults', []); +Session.setDefault('addMemberPopup.searching', false); +Session.setDefault('addMemberPopup.noResults', false); +Session.setDefault('addMemberPopup.loading', false); +Session.setDefault('addMemberPopup.error', ''); + + BlazeComponent.extendComponent({ onCreated() { - this.error = new ReactiveVar(''); - this.loading = new ReactiveVar(false); + // Use Session variables + this.searchTimeout = null; }, onRendered() { - this.find('.js-search-member input').focus(); + this.find('.js-search-member-input').focus(); this.setLoading(false); }, isBoardMember() { - const userId = this.currentData().__originalId; + const userId = this.currentData()._id; const user = ReactiveCache.getUser(userId); return user && user.isBoardMember(); }, @@ -1510,15 +1474,35 @@ BlazeComponent.extendComponent({ }, setError(error) { - this.error.set(error); + Session.set('addMemberPopup.error', error); }, setLoading(w) { - this.loading.set(w); + Session.set('addMemberPopup.loading', w); }, isLoading() { - return this.loading.get(); + return Session.get('addMemberPopup.loading'); + }, + + performSearch(query) { + if (!query || query.length < 2) { + Session.set('addMemberPopup.searchResults', []); + Session.set('addMemberPopup.noResults', false); + return; + } + + Session.set('addMemberPopup.searching', true); + Session.set('addMemberPopup.noResults', false); + + // Use the fallback search + const results = UserSearchIndex.search(query, { limit: 20 }).fetch(); + Session.set('addMemberPopup.searchResults', results); + Session.set('addMemberPopup.searching', false); + + if (results.length === 0) { + Session.set('addMemberPopup.noResults', true); + } }, inviteUser(idNameEmail) { @@ -1536,18 +1520,30 @@ BlazeComponent.extendComponent({ events() { return [ { - 'keyup input'() { + 'keyup .js-search-member-input'(event) { this.setError(''); + const query = event.target.value.trim(); + this.searchQuery.set(query); + + // Clear previous timeout + if (this.searchTimeout) { + clearTimeout(this.searchTimeout); + } + + // Debounce search + this.searchTimeout = setTimeout(() => { + this.performSearch(query); + }, 300); }, 'click .js-select-member'() { - const userId = this.currentData().__originalId; + const userId = this.currentData()._id; const currentBoard = Utils.getCurrentBoard(); if (!currentBoard.hasMember(userId)) { this.inviteUser(userId); } }, 'click .js-email-invite'() { - const idNameEmail = $('.js-search-member input').val(); + const idNameEmail = $('.js-search-member-input').val(); if (idNameEmail.indexOf('@') < 0 || this.isValidEmail(idNameEmail)) { this.inviteUser(idNameEmail); } else this.setError('email-invalid'); @@ -1558,7 +1554,35 @@ BlazeComponent.extendComponent({ }).register('addMemberPopup'); Template.addMemberPopup.helpers({ - searchIndex: () => UserSearchIndex, + searchResults() { + const results = Session.get('addMemberPopup.searchResults'); + console.log('searchResults helper called, returning:', results); + return results; + }, + searching() { + return Session.get('addMemberPopup.searching'); + }, + noResults() { + return Session.get('addMemberPopup.noResults'); + }, + loading() { + return Session.get('addMemberPopup.loading'); + }, + error() { + return Session.get('addMemberPopup.error'); + }, + isBoardMember() { + const userId = this._id; + const user = ReactiveCache.getUser(userId); + return user && user.isBoardMember(); + } +}) + +Template.addMemberPopupTest.helpers({ + searchResults() { + console.log('addMemberPopupTest searchResults helper called'); + return Session.get('addMemberPopup.searchResults') || []; + } }) BlazeComponent.extendComponent({ diff --git a/client/components/sidebar/sidebarCustomFields.jade b/client/components/sidebar/sidebarCustomFields.jade index d55379957..0d16559f8 100644 --- a/client/components/sidebar/sidebarCustomFields.jade +++ b/client/components/sidebar/sidebarCustomFields.jade @@ -4,7 +4,8 @@ template(name="customFieldsSidebar") li div.minicard-wrapper.js-minicard div.minicard - a.fa.fa-pencil.js-edit-custom-field.minicard-edit-button + a.js-edit-custom-field.minicard-edit-button + | ✏️ div.minicard-title +viewer =name @@ -13,7 +14,7 @@ template(name="customFieldsSidebar") if currentUser.isBoardMember hr a.sidebar-btn.js-open-create-custom-field - i.fa.fa-plus + | ➕ span {{_ 'createCustomField'}} template(name="createCustomFieldPopup") @@ -94,3 +95,7 @@ template(name="createCustomFieldPopup") template(name="deleteCustomFieldPopup") p {{_ "custom-field-delete-pop"}} button.js-confirm.negate.full(type="submit") {{_ 'delete'}} + +// Reuse the create form for editing to satisfy popup template lookup +template(name="editCustomFieldPopup") + +Template.dynamic(template="createCustomFieldPopup") diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade index 52a859744..918711b09 100644 --- a/client/components/sidebar/sidebarFilters.jade +++ b/client/components/sidebar/sidebarFilters.jade @@ -5,19 +5,19 @@ template(name="filterSidebar") h3 - i.fa.fa-trello + | 📋 | {{_ 'list-filter-label'}} ul.sidebar-list form.js-list-filter input(type="text") hr h3 - i.fa.fa-list-alt + | 📋 | {{_ 'filter-card-title-label'}} input.js-field-card-filter(type="text") hr h3 - i.fa.fa-tags + | 🏷️ | {{_ 'filter-labels-label'}} ul.sidebar-list li(class="{{#if Filter.labelIds.isSelected undefined}}active{{/if}}") @@ -25,7 +25,7 @@ template(name="filterSidebar") span.sidebar-list-item-description | {{_ 'filter-no-label'}} if Filter.labelIds.isSelected undefined - i.fa.fa-check + | ✅ each currentBoard.labels li a.name.js-toggle-label-filter @@ -39,7 +39,7 @@ template(name="filterSidebar") i.fa.fa-check hr h3 - i.fa.fa-users + | 👥 | {{_ 'filter-member-label'}} ul.sidebar-list li(class="{{#if Filter.members.isSelected undefined}}active{{/if}}") @@ -47,7 +47,7 @@ template(name="filterSidebar") span.sidebar-list-item-description | {{_ 'filter-no-member'}} if Filter.members.isSelected undefined - i.fa.fa-check + | ✅ each currentBoard.activeMembers with getUser userId li(class="{{#if Filter.members.isSelected _id}}active{{/if}}") @@ -57,10 +57,10 @@ template(name="filterSidebar") = profile.fullname | ({{ username }}) if Filter.members.isSelected _id - i.fa.fa-check + | ✅ hr h3 - i.fa.fa-user + | 👤 | {{_ 'filter-assignee-label'}} ul.sidebar-list li(class="{{#if Filter.assignees.isSelected undefined}}active{{/if}}") @@ -78,11 +78,11 @@ template(name="filterSidebar") = profile.fullname | ({{ username }}) if Filter.assignees.isSelected _id - i.fa.fa-check + | ✅ hr h3 - i.fa.fa-list-alt + | 📅 | {{_ 'filter-dates-label' }} ul.sidebar-list li(class="{{#if Filter.dueAt.isSelected 'noDate'}}active{{/if}}") @@ -123,7 +123,7 @@ template(name="filterSidebar") i.fa.fa-check hr h3 - i.fa.fa-list-alt + | 📋 | {{_ 'filter-custom-fields-label'}} ul.sidebar-list li(class="{{#if Filter.customFields.isSelected undefined}}active{{/if}}") @@ -131,7 +131,7 @@ template(name="filterSidebar") span.sidebar-list-item-description | {{_ 'filter-no-custom-fields'}} if Filter.customFields.isSelected undefined - i.fa.fa-check + | ✅ each currentBoard.customFields li(class="{{#if Filter.customFields.isSelected _id}}active{{/if}}") a.name.js-toggle-custom-fields-filter @@ -163,15 +163,15 @@ template(name="filterSidebar") if Filter.isActive hr a.sidebar-btn.js-clear-all - i.fa.fa-filter + | 🔍 span {{_ 'filter-clear'}} a.sidebar-btn.js-filter-to-selection - i.fa.fa-check-square-o + | ☑️ span {{_ 'filter-to-selection'}} template(name="multiselectionSidebar") h3 - i.fa.fa-tags + | 🏷️ | {{_ 'multi-selection-label'}} ul.sidebar-list each currentBoard.labels @@ -184,12 +184,12 @@ template(name="multiselectionSidebar") else span.quiet {{_ "label-default" (_ (concat "color-" color))}} if allSelectedElementHave 'label' _id - i.fa.fa-check + | ✅ else if someSelectedElementHave 'label' _id - i.fa.fa-ellipsis-h + | ⋯ hr h3 - i.fa.fa-users + | 👥 | {{_ 'multi-selection-member'}} ul.sidebar-list each currentBoard.activeMembers @@ -201,16 +201,16 @@ template(name="multiselectionSidebar") = profile.fullname | ({{ username }}) if allSelectedElementHave 'member' _id - i.fa.fa-check + | ✅ else if someSelectedElementHave 'member' _id - i.fa.fa-ellipsis-h + | ⋯ if currentUser.isBoardAdmin hr a.sidebar-btn.js-move-selection - i.fa.fa-share + | 📤 span {{_ 'move-selection'}} a.sidebar-btn.js-archive-selection - i.fa.fa-archive + | 📦 span {{_ 'archive-selection'}} template(name="disambiguateMultiLabelPopup") diff --git a/client/components/sidebar/sidebarMigrations.jade b/client/components/sidebar/sidebarMigrations.jade new file mode 100644 index 000000000..f5f7f08f8 --- /dev/null +++ b/client/components/sidebar/sidebarMigrations.jade @@ -0,0 +1,109 @@ +template(name='migrationsSidebar') + if currentUser.isBoardAdmin + .sidebar-migrations + h3 + | 🔧 + | {{_ 'migrations'}} + p.quiet {{_ 'migrations-description'}} + + .migrations-list + h4 {{_ 'board-migrations'}} + .migration-item + a.js-run-migration(data-migration="comprehensive") + .migration-name + | {{_ 'comprehensive-board-migration'}} + .migration-status + if comprehensiveMigrationNeeded + span.badge.badge-warning {{_ 'migration-needed'}} + else + span.badge.badge-success {{_ 'migration-complete'}} + + .migration-item + a.js-run-migration(data-migration="fixMissingLists") + .migration-name + | {{_ 'fix-missing-lists-migration'}} + .migration-status + if fixMissingListsNeeded + span.badge.badge-warning {{_ 'migration-needed'}} + else + span.badge.badge-success {{_ 'migration-complete'}} + + .migration-item + a.js-run-migration(data-migration="deleteDuplicateEmptyLists") + .migration-name + | {{_ 'delete-duplicate-empty-lists-migration'}} + .migration-status + if deleteDuplicateEmptyListsNeeded + span.badge.badge-warning {{_ 'migration-needed'}} + else + span.badge.badge-success {{_ 'migration-complete'}} + + .migration-item + a.js-run-migration(data-migration="restoreLostCards") + .migration-name + | {{_ 'restore-lost-cards-migration'}} + .migration-status + if restoreLostCardsNeeded + span.badge.badge-warning {{_ 'migration-needed'}} + else + span.badge.badge-success {{_ 'migration-complete'}} + + .migration-item + a.js-run-migration(data-migration="restoreAllArchived") + .migration-name + | {{_ 'restore-all-archived-migration'}} + .migration-status + if restoreAllArchivedNeeded + span.badge.badge-warning {{_ 'migration-needed'}} + else + span.badge.badge-success {{_ 'migration-complete'}} + + .migration-item + a.js-run-migration(data-migration="fixAvatarUrls") + .migration-name + | {{_ 'fix-avatar-urls-migration'}} + .migration-status + if fixAvatarUrlsNeeded + span.badge.badge-warning {{_ 'migration-needed'}} + else + span.badge.badge-success {{_ 'migration-complete'}} + + .migration-item + a.js-run-migration(data-migration="fixAllFileUrls") + .migration-name + | {{_ 'fix-all-file-urls-migration'}} + .migration-status + if fixAllFileUrlsNeeded + span.badge.badge-warning {{_ 'migration-needed'}} + else + span.badge.badge-success {{_ 'migration-complete'}} + else + p.quiet {{_ 'migrations-admin-only'}} + +template(name='runComprehensiveMigrationPopup') + p {{_ 'run-comprehensive-migration-confirm'}} + button.js-confirm.primary.full(type="submit") {{_ 'run-migration'}} + +template(name='runFixMissingListsMigrationPopup') + p {{_ 'run-fix-missing-lists-migration-confirm'}} + button.js-confirm.primary.full(type="submit") {{_ 'run-migration'}} + +template(name='runDeleteDuplicateEmptyListsMigrationPopup') + p {{_ 'run-delete-duplicate-empty-lists-migration-confirm'}} + button.js-confirm.primary.full(type="submit") {{_ 'run-migration'}} + +template(name='runRestoreLostCardsMigrationPopup') + p {{_ 'run-restore-lost-cards-migration-confirm'}} + button.js-confirm.primary.full(type="submit") {{_ 'run-migration'}} + +template(name='runRestoreAllArchivedMigrationPopup') + p {{_ 'run-restore-all-archived-migration-confirm'}} + button.js-confirm.primary.full(type="submit") {{_ 'run-migration'}} + +template(name='runFixAvatarUrlsMigrationPopup') + p {{_ 'run-fix-avatar-urls-migration-confirm'}} + button.js-confirm.primary.full(type="submit") {{_ 'run-migration'}} + +template(name='runFixAllFileUrlsMigrationPopup') + p {{_ 'run-fix-all-file-urls-migration-confirm'}} + button.js-confirm.primary.full(type="submit") {{_ 'run-migration'}} diff --git a/client/components/sidebar/sidebarMigrations.js b/client/components/sidebar/sidebarMigrations.js new file mode 100644 index 000000000..89d3343ec --- /dev/null +++ b/client/components/sidebar/sidebarMigrations.js @@ -0,0 +1,341 @@ +import { ReactiveCache } from '/imports/reactiveCache'; +import { TAPi18n } from '/imports/i18n'; +import { migrationProgressManager } from '/client/components/migrationProgress'; + +BlazeComponent.extendComponent({ + onCreated() { + this.migrationStatuses = new ReactiveVar({}); + this.loadMigrationStatuses(); + }, + + loadMigrationStatuses() { + const boardId = Session.get('currentBoard'); + if (!boardId) return; + + // Check comprehensive migration + Meteor.call('comprehensiveBoardMigration.needsMigration', boardId, (err, res) => { + if (!err) { + const statuses = this.migrationStatuses.get(); + statuses.comprehensive = res; + this.migrationStatuses.set(statuses); + } + }); + + // Check fix missing lists migration + Meteor.call('fixMissingListsMigration.needsMigration', boardId, (err, res) => { + if (!err) { + const statuses = this.migrationStatuses.get(); + statuses.fixMissingLists = res; + this.migrationStatuses.set(statuses); + } + }); + + // Check delete duplicate empty lists migration + Meteor.call('deleteDuplicateEmptyLists.needsMigration', boardId, (err, res) => { + if (!err) { + const statuses = this.migrationStatuses.get(); + statuses.deleteDuplicateEmptyLists = res; + this.migrationStatuses.set(statuses); + } + }); + + // Check restore lost cards migration + Meteor.call('restoreLostCards.needsMigration', boardId, (err, res) => { + if (!err) { + const statuses = this.migrationStatuses.get(); + statuses.restoreLostCards = res; + this.migrationStatuses.set(statuses); + } + }); + + // Check restore all archived migration + Meteor.call('restoreAllArchived.needsMigration', boardId, (err, res) => { + if (!err) { + const statuses = this.migrationStatuses.get(); + statuses.restoreAllArchived = res; + this.migrationStatuses.set(statuses); + } + }); + + // Check fix avatar URLs migration (board-specific) + Meteor.call('fixAvatarUrls.needsMigration', boardId, (err, res) => { + if (!err) { + const statuses = this.migrationStatuses.get(); + statuses.fixAvatarUrls = res; + this.migrationStatuses.set(statuses); + } + }); + + // Check fix all file URLs migration (board-specific) + Meteor.call('fixAllFileUrls.needsMigration', boardId, (err, res) => { + if (!err) { + const statuses = this.migrationStatuses.get(); + statuses.fixAllFileUrls = res; + this.migrationStatuses.set(statuses); + } + }); + }, + + comprehensiveMigrationNeeded() { + return this.migrationStatuses.get().comprehensive === true; + }, + + fixMissingListsNeeded() { + return this.migrationStatuses.get().fixMissingLists === true; + }, + + deleteDuplicateEmptyListsNeeded() { + return this.migrationStatuses.get().deleteDuplicateEmptyLists === true; + }, + + restoreLostCardsNeeded() { + return this.migrationStatuses.get().restoreLostCards === true; + }, + + restoreAllArchivedNeeded() { + return this.migrationStatuses.get().restoreAllArchived === true; + }, + + fixAvatarUrlsNeeded() { + return this.migrationStatuses.get().fixAvatarUrls === true; + }, + + fixAllFileUrlsNeeded() { + return this.migrationStatuses.get().fixAllFileUrls === true; + }, + + // Simulate migration progress updates using the global progress popup + async simulateMigrationProgress(progressSteps) { + const totalSteps = progressSteps.length; + for (let i = 0; i < progressSteps.length; i++) { + const step = progressSteps[i]; + const overall = Math.round(((i + 1) / totalSteps) * 100); + + // Start step + migrationProgressManager.updateProgress({ + overallProgress: overall, + currentStep: i + 1, + totalSteps, + stepName: step.step, + stepProgress: 0, + stepStatus: `Starting ${step.name}...`, + stepDetails: null, + boardId: Session.get('currentBoard'), + }); + + const stepDuration = step.duration; + const updateInterval = 100; + const totalUpdates = Math.max(1, Math.floor(stepDuration / updateInterval)); + for (let j = 0; j < totalUpdates; j++) { + const per = Math.round(((j + 1) / totalUpdates) * 100); + migrationProgressManager.updateProgress({ + overallProgress: overall, + currentStep: i + 1, + totalSteps, + stepName: step.step, + stepProgress: per, + stepStatus: `Processing ${step.name}...`, + stepDetails: { progress: `${per}%` }, + boardId: Session.get('currentBoard'), + }); + // eslint-disable-next-line no-await-in-loop + await new Promise((r) => setTimeout(r, updateInterval)); + } + + // Complete step + migrationProgressManager.updateProgress({ + overallProgress: overall, + currentStep: i + 1, + totalSteps, + stepName: step.step, + stepProgress: 100, + stepStatus: `${step.name} completed`, + stepDetails: { status: 'completed' }, + boardId: Session.get('currentBoard'), + }); + } + }, + + runMigration(migrationType) { + const boardId = Session.get('currentBoard'); + + let methodName; + let methodArgs = []; + + switch (migrationType) { + case 'comprehensive': + methodName = 'comprehensiveBoardMigration.execute'; + methodArgs = [boardId]; + break; + + case 'fixMissingLists': + methodName = 'fixMissingListsMigration.execute'; + methodArgs = [boardId]; + break; + + case 'deleteDuplicateEmptyLists': + methodName = 'deleteDuplicateEmptyLists.execute'; + methodArgs = [boardId]; + break; + + case 'restoreLostCards': + methodName = 'restoreLostCards.execute'; + methodArgs = [boardId]; + break; + + case 'restoreAllArchived': + methodName = 'restoreAllArchived.execute'; + methodArgs = [boardId]; + break; + + case 'fixAvatarUrls': + methodName = 'fixAvatarUrls.execute'; + methodArgs = [boardId]; + break; + + case 'fixAllFileUrls': + methodName = 'fixAllFileUrls.execute'; + methodArgs = [boardId]; + break; + } + + if (methodName) { + // Define simulated steps per migration type + const stepsByType = { + comprehensive: [ + { step: 'analyze_board_structure', name: 'Analyze Board Structure', duration: 800 }, + { step: 'fix_orphaned_cards', name: 'Fix Orphaned Cards', duration: 1200 }, + { step: 'convert_shared_lists', name: 'Convert Shared Lists', duration: 1000 }, + { step: 'ensure_per_swimlane_lists', name: 'Ensure Per-Swimlane Lists', duration: 800 }, + { step: 'validate_migration', name: 'Validate Migration', duration: 800 }, + { step: 'fix_avatar_urls', name: 'Fix Avatar URLs', duration: 600 }, + { step: 'fix_attachment_urls', name: 'Fix Attachment URLs', duration: 600 }, + ], + fixMissingLists: [ + { step: 'analyze_lists', name: 'Analyze Lists', duration: 600 }, + { step: 'create_missing_lists', name: 'Create Missing Lists', duration: 900 }, + { step: 'update_cards', name: 'Update Cards', duration: 900 }, + { step: 'finalize', name: 'Finalize', duration: 400 }, + ], + deleteDuplicateEmptyLists: [ + { step: 'convert_shared_lists', name: 'Convert Shared Lists', duration: 700 }, + { step: 'delete_duplicate_empty_lists', name: 'Delete Duplicate Empty Lists', duration: 800 }, + ], + restoreLostCards: [ + { step: 'ensure_lost_cards_swimlane', name: 'Ensure Lost Cards Swimlane', duration: 600 }, + { step: 'restore_lists', name: 'Restore Lists', duration: 800 }, + { step: 'restore_cards', name: 'Restore Cards', duration: 1000 }, + ], + restoreAllArchived: [ + { step: 'restore_swimlanes', name: 'Restore Swimlanes', duration: 800 }, + { step: 'restore_lists', name: 'Restore Lists', duration: 900 }, + { step: 'restore_cards', name: 'Restore Cards', duration: 1000 }, + { step: 'fix_missing_ids', name: 'Fix Missing IDs', duration: 600 }, + ], + fixAvatarUrls: [ + { step: 'scan_users', name: 'Checking board member avatars', duration: 500 }, + { step: 'fix_urls', name: 'Fixing avatar URLs', duration: 900 }, + ], + fixAllFileUrls: [ + { step: 'scan_files', name: 'Checking board file attachments', duration: 600 }, + { step: 'fix_urls', name: 'Fixing file URLs', duration: 1000 }, + ], + }; + + const steps = stepsByType[migrationType] || [ + { step: 'running', name: 'Running Migration', duration: 1000 }, + ]; + + // Kick off popup and simulated progress + migrationProgressManager.startMigration(); + const progressPromise = this.simulateMigrationProgress(steps); + + // Start migration call + const callPromise = new Promise((resolve, reject) => { + Meteor.call(methodName, ...methodArgs, (err, result) => { + if (err) return reject(err); + return resolve(result); + }); + }); + + Promise.allSettled([callPromise, progressPromise]).then(([callRes]) => { + if (callRes.status === 'rejected') { + migrationProgressManager.failMigration(callRes.reason); + } else { + const result = callRes.value; + // Summarize result details in the popup + let summary = {}; + if (result && result.results) { + // Comprehensive returns {success, results} + const r = result.results; + summary = { + totalCardsProcessed: r.totalCardsProcessed, + totalListsProcessed: r.totalListsProcessed, + totalListsCreated: r.totalListsCreated, + }; + } else if (result && result.changes) { + // Many migrations return a changes string array + summary = { changes: result.changes.join(' | ') }; + } else if (result && typeof result === 'object') { + summary = result; + } + + migrationProgressManager.updateProgress({ + overallProgress: 100, + currentStep: steps.length, + totalSteps: steps.length, + stepName: 'completed', + stepProgress: 100, + stepStatus: 'Migration completed', + stepDetails: summary, + boardId: Session.get('currentBoard'), + }); + + migrationProgressManager.completeMigration(); + + // Refresh status badges slightly after + Meteor.setTimeout(() => { + this.loadMigrationStatuses(); + }, 1000); + } + }); + } + }, + + events() { + const self = this; // Capture component reference + + return [ + { + 'click .js-run-migration[data-migration="comprehensive"]': Popup.afterConfirm('runComprehensiveMigration', function() { + self.runMigration('comprehensive'); + Popup.back(); + }), + 'click .js-run-migration[data-migration="fixMissingLists"]': Popup.afterConfirm('runFixMissingListsMigration', function() { + self.runMigration('fixMissingLists'); + Popup.back(); + }), + 'click .js-run-migration[data-migration="deleteDuplicateEmptyLists"]': Popup.afterConfirm('runDeleteDuplicateEmptyListsMigration', function() { + self.runMigration('deleteDuplicateEmptyLists'); + Popup.back(); + }), + 'click .js-run-migration[data-migration="restoreLostCards"]': Popup.afterConfirm('runRestoreLostCardsMigration', function() { + self.runMigration('restoreLostCards'); + Popup.back(); + }), + 'click .js-run-migration[data-migration="restoreAllArchived"]': Popup.afterConfirm('runRestoreAllArchivedMigration', function() { + self.runMigration('restoreAllArchived'); + Popup.back(); + }), + 'click .js-run-migration[data-migration="fixAvatarUrls"]': Popup.afterConfirm('runFixAvatarUrlsMigration', function() { + self.runMigration('fixAvatarUrls'); + Popup.back(); + }), + 'click .js-run-migration[data-migration="fixAllFileUrls"]': Popup.afterConfirm('runFixAllFileUrlsMigration', function() { + self.runMigration('fixAllFileUrls'); + Popup.back(); + }), + }, + ]; + }, +}).register('migrationsSidebar'); diff --git a/client/components/swimlanes/miniswimlane.jade b/client/components/swimlanes/miniswimlane.jade index d4be85994..890187795 100644 --- a/client/components/swimlanes/miniswimlane.jade +++ b/client/components/swimlanes/miniswimlane.jade @@ -3,6 +3,6 @@ template(name="miniswimlane") class="minicard-{{colorClass}}") .minicard-title .handle - .fa.fa-arrows + | ↕️ +viewer = title diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index d14686163..a0a44eb7f 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -23,88 +23,102 @@ template(name="swimlaneFixedHeader") +viewer | {{isTitleDefault title}} .swimlane-header-menu - unless currentUser.isCommentOnly - a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}") - a.fa.fa-navicon.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}") - //// TODO: Collapse Swimlane: make button working, etc. - //unless collapsed - // a.js-collapse-swimlane(title="{{_ 'collapse'}}") - // i.fa.fa-arrow-down.swimlane-header-collapse-down - // i.fa.fa-arrow-up.swimlane-header-collapse-up - //if collapsed - // a.js-collapse-swimlane(title="{{_ 'uncollapse'}}") - // i.fa.fa-arrow-up.swimlane-header-collapse-up - // i.fa.fa-arrow-down.swimlane-header-collapse-down - unless isTouchScreen - if isShowDesktopDragHandles - a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle - if isTouchScreen - a.swimlane-header-miniscreen-handle.handle.fa.fa-arrows.js-swimlane-header-handle + if currentUser + unless currentUser.isCommentOnly + unless currentUser.isWorker + a.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}") + | ➕ + a.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}") + | ☰ + //// TODO: Collapse Swimlane: make button working, etc. + //unless collapsed + // a.js-collapse-swimlane(title="{{_ 'collapse'}}") + // i.fa.fa-arrow-down.swimlane-header-collapse-down + // ⬆️.swimlane-header-collapse-up + //if collapsed + // a.js-collapse-swimlane(title="{{_ 'uncollapse'}}") + // ⬆️.swimlane-header-collapse-up + // i.fa.fa-arrow-down.swimlane-header-collapse-down + unless isTouchScreen + a.swimlane-header-handle.handle.js-swimlane-header-handle + | ↕️ + if isTouchScreen + a.swimlane-header-miniscreen-handle.handle.js-swimlane-header-handle + | ↕️ template(name="editSwimlaneTitleForm") .list-composer input.list-name-input.full-line(type="text" value="{{isTitleDefault title}}" autofocus) .edit-controls.clearfix button.primary.confirm(type="submit") {{_ 'save'}} - a.fa.fa-times-thin.js-close-inlined-form + a.js-close-inlined-form + | ❌ template(name="swimlaneActionPopup") - unless currentUser.isCommentOnly - ul.pop-over-list - if currentUser.isBoardAdmin - li: a.js-set-swimlane-color - i.fa.fa-paint-brush - | {{_ 'select-color'}} - li: a.js-set-swimlane-height - i.fa.fa-arrows-v - | {{_ 'set-swimlane-height'}} - if currentUser.isBoardAdmin - unless this.isTemplateContainer - hr - ul.pop-over-list - li: a.js-close-swimlane - i.fa.fa-arrow-right - i.fa.fa-archive - | {{_ 'archive-swimlane'}} - ul.pop-over-list - li: a.js-copy-swimlane - i.fa.fa-copy - | {{_ 'copy-swimlane'}} - ul.pop-over-list - li: a.js-move-swimlane - i.fa.fa-arrow-up - | {{_ 'move-swimlane'}} + if currentUser + unless currentUser.isCommentOnly + ul.pop-over-list + if currentUser.isBoardAdmin + li: a.js-set-swimlane-color + | 🎨 + | {{_ 'select-color'}} + li: a.js-set-swimlane-height + | ↕️ + | {{_ 'set-swimlane-height'}} + if currentUser.isBoardAdmin + unless this.isTemplateContainer + hr + ul.pop-over-list + li: a.js-close-swimlane + | ▶️ + | 📦 + | {{_ 'archive-swimlane'}} + ul.pop-over-list + li: a.js-copy-swimlane + | 📋 + | {{_ 'copy-swimlane'}} + ul.pop-over-list + li: a.js-move-swimlane + | ⬆️ + | {{_ 'move-swimlane'}} template(name="swimlaneAddPopup") - unless currentUser.isCommentOnly - form - input.swimlane-name-input.full-line(type="text" placeholder="{{_ 'add-swimlane'}}" - autocomplete="off" autofocus) - .edit-controls.clearfix - button.primary.confirm(type="submit") {{_ 'add'}} - unless currentBoard.isTemplatesBoard - unless currentBoard.isTemplateBoard - span.quiet - | {{_ 'or'}} - a.js-swimlane-template {{_ 'template'}} + if currentUser + unless currentUser.isCommentOnly + form + input.swimlane-name-input.full-line(type="text" placeholder="{{_ 'add-swimlane'}}" + autocomplete="off" autofocus) + .edit-controls.clearfix + button.primary.confirm(type="submit") {{_ 'add'}} + unless currentBoard.isTemplatesBoard + unless currentBoard.isTemplateBoard + span.quiet + | {{_ 'or'}} + a.js-swimlane-template {{_ 'template'}} template(name="setSwimlaneColorPopup") - form.edit-label - .palette-colors: each colors - span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") - if(isSelected color) - i.fa.fa-check - button.primary.confirm.js-submit {{_ 'save'}} - button.js-remove-color.negate.wide.right {{_ 'unset-color'}} + form.edit-label.swimlane-color-popup + // Align content to left and remove default gutter + .flush-left + .palette-colors(style="margin-left:0; padding-left:0; justify-content:flex-start;") + each colors + span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") + if(isSelected color) + | ✅ + // Buttons aligned left too + .flush-left + button.primary.confirm.js-submit(style="margin-left:0") {{_ 'save'}} + button.js-remove-color.negate.wide.right(style="margin-left:8px") {{_ 'unset-color'}} template(name="setSwimlaneHeightPopup") - #js-swimlane-height-edit - label a) {{_ 'set-swimlane-height-value'}} - label b) -1 - p - input.swimlane-height-value(type="number" value="{{ swimlaneHeightValue }}" min="100") - input.swimlane-height-apply(type="submit" value="{{_ 'apply'}}") - input.swimlane-height-error + .flush-left.swimlane-height-popup + #js-swimlane-height-edit + label a) {{_ 'set-swimlane-height-value'}} + label b) -1 + p + input.swimlane-height-value(type="number" value="{{ swimlaneHeightValue }}" min="100") + input.swimlane-height-apply(type="submit" value="{{_ 'apply'}}") + input.swimlane-height-error template(name="swimlaneHeightErrorPopup") .swimlane-height-invalid diff --git a/client/components/swimlanes/swimlaneHeader.js b/client/components/swimlanes/swimlaneHeader.js index 17988f454..c0ef35453 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -178,6 +178,11 @@ BlazeComponent.extendComponent({ events() { return [ { + 'submit form'(event) { + event.preventDefault(); + this.currentSwimlane.setColor(this.currentColor.get()); + Popup.back(); + }, 'click .js-palette-color'() { this.currentColor.set(this.currentData().color); }, diff --git a/client/components/swimlanes/swimlanes.css b/client/components/swimlanes/swimlanes.css index 0bb7727f0..83540549f 100644 --- a/client/components/swimlanes/swimlanes.css +++ b/client/components/swimlanes/swimlanes.css @@ -8,6 +8,7 @@ flex-direction: row; overflow: auto; max-height: 100%; + position: relative; } .swimlane-header-menu .swimlane-header-collapse-down { font-size: 50%; @@ -67,11 +68,16 @@ text-overflow: ellipsis; word-wrap: break-word; text-align: center; + position: relative; + z-index: 10; + pointer-events: auto; } .swimlane .swimlane-header-wrap .swimlane-header-menu { position: absolute; padding: 5px 5px; font-size: 22px; + z-index: 20; + pointer-events: auto; } @media print { .swimlane .swimlane-header-wrap .swimlane-header-menu { @@ -97,14 +103,27 @@ display: flex; align-items: center; justify-content: center; + cursor: move; + z-index: 15; + pointer-events: auto; } .swimlane .swimlane-header-wrap .swimlane-header-miniscreen-handle { position: absolute; padding: 7px; top: 50%; transform: translateY(-50%); - left: 87vw; + right: 10px; font-size: 24px; + cursor: move; + z-index: 15; + pointer-events: auto; +} + +/* Safety: ensure wrapper is interactive and above list content */ +.swimlane .swimlane-header-wrap { + position: relative; + z-index: 9; + pointer-events: auto; } #js-swimlane-height-edit .swimlane-height-error { display: none; @@ -216,3 +235,106 @@ background: #4b0082 !important; color: #fff !important; } + +/* Swimlane resize handle */ +.swimlane-resize-handle { + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 8px; + background: transparent; + cursor: row-resize; + z-index: 20; + border-top: 2px solid transparent; + transition: all 0.2s ease; + border-radius: 2px; + /* Ensure the handle is clickable */ + pointer-events: auto; +} + +/* Show resize handle only on hover */ +.swimlane:hover .swimlane-resize-handle { + background: rgba(0, 0, 0, 0.1); + border-top-color: rgba(0, 0, 0, 0.2); +} + +/* Add a subtle resize indicator line at the bottom of swimlane on hover */ +.swimlane:hover .swimlane-resize-handle::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 2px; + background: rgba(0, 123, 255, 0.3); + z-index: 21; + transition: all 0.2s ease; + border-radius: 1px; +} + +/* Make the indicator line more prominent when hovering over the resize handle */ +.swimlane-resize-handle:hover::after { + background: rgba(0, 123, 255, 0.6) !important; + height: 3px !important; + box-shadow: 0 0 4px rgba(0, 123, 255, 0.2); +} + +.swimlane-resize-handle:hover { + background: rgba(0, 123, 255, 0.4) !important; + border-top-color: #0079bf !important; + box-shadow: 0 0 4px rgba(0, 123, 255, 0.3); +} + +.swimlane-resize-handle:active { + background: rgba(0, 123, 255, 0.6) !important; + border-top-color: #0079bf !important; + box-shadow: 0 0 6px rgba(0, 123, 255, 0.4); +} + +/* Add a subtle indicator line */ +.swimlane-resize-handle::before { + content: ''; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + width: 20px; + height: 2px; + background: rgba(0, 123, 255, 0.6); + border-radius: 1px; + opacity: 0; + transition: opacity 0.2s ease; +} + +.swimlane-resize-handle:hover::before { + opacity: 1; +} + +/* Visual feedback during resize */ +.swimlane.swimlane-resizing { + transition: none !important; + box-shadow: 0 0 10px rgba(0, 123, 255, 0.3); + /* Ensure the swimlane maintains its new height during resize */ + flex: none !important; + flex-basis: auto !important; + flex-grow: 0 !important; + flex-shrink: 0 !important; + /* Override any conflicting layout properties */ + display: flex !important; + position: relative !important; + /* Force height to be respected */ + height: var(--swimlane-height, auto) !important; + min-height: var(--swimlane-height, auto) !important; + max-height: var(--swimlane-height, auto) !important; + /* Ensure the height is applied immediately */ + overflow: visible !important; +} + +body.swimlane-resizing-active { + cursor: row-resize !important; +} + +body.swimlane-resizing-active * { + cursor: row-resize !important; +} diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index 0afe02dbe..25e634573 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -4,6 +4,7 @@ template(name="swimlane") unless collapseSwimlane .swimlane.js-lists.js-swimlane.dragscroll(id="swimlane-{{_id}}" style="height:{{swimlaneHeight}};") + .swimlane-resize-handle.js-swimlane-resize-handle.nodragscroll if isMiniScreen if currentListIsInThisSwimlane _id +list(currentList) @@ -59,7 +60,8 @@ template(name="addListForm") option(value="{{_id}}" selected=currentBoard.getLastList.title) {{title}} .edit-controls.clearfix button.primary.confirm(type="submit") {{_ 'save'}} - .fa.fa-times-thin.js-close-inlined-form + .js-close-inlined-form + | ❌ unless currentBoard.isTemplatesBoard unless currentBoard.isTemplateBoard span.quiet @@ -67,24 +69,26 @@ template(name="addListForm") a.js-list-template {{_ 'template'}} else a.open-list-composer.js-open-inlined-form(title="{{_ 'add-list'}}") - i.fa.fa-plus + | ➕ template(name="moveSwimlanePopup") - unless currentUser.isWorker - label {{_ 'boards'}}: - select.js-select-boards(autofocus) - each toBoard in toBoards - option(value="{{toBoard._id}}") {{toBoard.title}} + if currentUser + unless currentUser.isWorker + label {{_ 'boards'}}: + select.js-select-boards(autofocus) + each toBoard in toBoards + option(value="{{toBoard._id}}") {{toBoard.title}} - .edit-controls.clearfix - button.primary.confirm.js-done {{_ 'done'}} + .edit-controls.clearfix + button.primary.confirm.js-done {{_ 'done'}} template(name="copySwimlanePopup") - unless currentUser.isWorker - label {{_ 'boards'}}: - select.js-select-boards(autofocus) - each toBoard in toBoards - option(value="{{toBoard._id}}" selected="{{#if $eq toBoard.title board.title}}1{{/if}}") {{toBoard.title}} + if currentUser + unless currentUser.isWorker + label {{_ 'boards'}}: + select.js-select-boards(autofocus) + each toBoard in toBoards + option(value="{{toBoard._id}}" selected="{{#if $eq toBoard.title board.title}}1{{/if}}") {{toBoard.title}} - .edit-controls.clearfix - button.primary.confirm.js-done {{_ 'done'}} + .edit-controls.clearfix + button.primary.confirm.js-done {{_ 'done'}} diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index 3db21c927..e0dd896d5 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -1,6 +1,9 @@ import { ReactiveCache } from '/imports/reactiveCache'; +import dragscroll from '@wekanteam/dragscroll'; const { calculateIndex } = Utils; + + function currentListIsInThisSwimlane(swimlaneId) { const currentList = Utils.getCurrentList(); return ( @@ -43,6 +46,18 @@ function currentCardIsInThisList(listId, swimlaneId) { } function initSortable(boardComponent, $listsDom) { + // Safety check: ensure we have valid DOM elements + if (!$listsDom || $listsDom.length === 0) { + console.error('initSortable: No valid DOM elements provided'); + return; + } + + // Check if sortable is already initialized + if ($listsDom.data('uiSortable') || $listsDom.data('sortable')) { + $listsDom.sortable('destroy'); + } + + // We want to animate the card details window closing. We rely on CSS // transition for the actual animation. $listsDom._uihooks = { @@ -62,18 +77,68 @@ function initSortable(boardComponent, $listsDom) { }, }; - $listsDom.sortable({ - connectWith: '.js-swimlane, .js-lists', - tolerance: 'pointer', - helper: 'clone', - items: '.js-list:not(.js-list-composer)', - placeholder: 'js-list placeholder', - distance: 7, + + // Add click debugging for drag handles + $listsDom.on('mousedown', '.js-list-handle', function(e) { + e.stopPropagation(); + }); + + $listsDom.on('mousedown', '.js-list-header', function(e) { + }); + + // Add debugging for any mousedown on lists + $listsDom.on('mousedown', '.js-list', function(e) { + }); + + // Add debugging for sortable events + $listsDom.on('sortstart', function(e, ui) { + }); + + $listsDom.on('sortbeforestop', function(e, ui) { + }); + + $listsDom.on('sortstop', function(e, ui) { + }); + + try { + $listsDom.sortable({ + connectWith: '.js-swimlane, .js-lists', + tolerance: 'pointer', + appendTo: '.board-canvas', + helper(evt, item) { + const helper = item.clone(); + helper.css('z-index', 1000); + return helper; + }, + items: '.js-list:not(.js-list-composer)', + placeholder: 'list placeholder', + distance: 3, + forcePlaceholderSize: true, + cursor: 'move', start(evt, ui) { + ui.helper.css('z-index', 1000); ui.placeholder.height(ui.helper.height()); ui.placeholder.width(ui.helper.width()); EscapeActions.executeUpTo('popup-close'); boardComponent.setIsDragging(true); + + // Add visual feedback for list being dragged + ui.item.addClass('ui-sortable-helper'); + + // Disable dragscroll during list dragging to prevent interference + try { + dragscroll.reset(); + } catch (e) { + } + + // Also disable dragscroll on all swimlanes during list dragging + $('.js-swimlane').each(function() { + $(this).removeClass('dragscroll'); + }); + }, + beforeStop(evt, ui) { + // Clean up visual feedback + ui.item.removeClass('ui-sortable-helper'); }, stop(evt, ui) { // To attribute the new index number, we need to get the DOM element @@ -83,15 +148,37 @@ function initSortable(boardComponent, $listsDom) { const sortIndex = calculateIndex(prevListDom, nextListDom, 1); const listDomElement = ui.item.get(0); - const list = Blaze.getData(listDomElement); + if (!listDomElement) { + console.error('List DOM element not found during drag stop'); + return; + } + + let list; + try { + list = Blaze.getData(listDomElement); + } catch (error) { + console.error('Error getting list data:', error); + return; + } + + if (!list) { + console.error('List data not found for element:', listDomElement); + return; + } // Detect if the list was dropped in a different swimlane const targetSwimlaneDom = ui.item.closest('.js-swimlane'); let targetSwimlaneId = null; + if (targetSwimlaneDom.length > 0) { // List was dropped in a swimlane - targetSwimlaneId = targetSwimlaneDom.attr('id').replace('swimlane-', ''); + try { + targetSwimlaneId = targetSwimlaneDom.attr('id').replace('swimlane-', ''); + } catch (error) { + console.error('Error getting target swimlane ID:', error); + return; + } } else { // List was dropped in lists view (not swimlanes view) // In this case, assign to the default swimlane @@ -127,9 +214,6 @@ function initSortable(boardComponent, $listsDom) { // If the list was dropped in a different swimlane, update the swimlaneId if (isDifferentSwimlane) { updateData.swimlaneId = targetSwimlaneId; - if (process.env.DEBUG === 'true') { - console.log(`Moving list "${list.title}" from swimlane ${originalSwimlaneId} to swimlane ${targetSwimlaneId}`); - } // Move all cards in the list to the new swimlane const cardsInList = ReactiveCache.getCards({ @@ -141,59 +225,103 @@ function initSortable(boardComponent, $listsDom) { card.move(list.boardId, targetSwimlaneId, list._id); }); - if (process.env.DEBUG === 'true') { - console.log(`Moved ${cardsInList.length} cards to swimlane ${targetSwimlaneId}`); - } // Don't cancel the sortable when moving to a different swimlane // The DOM move should be allowed to complete - } else { - // If staying in the same swimlane, cancel the sortable to prevent DOM manipulation issues - $listsDom.sortable('cancel'); + } + // Allow reordering within the same swimlane by not canceling the sortable + + try { + Lists.update(list._id, { + $set: updateData, + }); + } catch (error) { + console.error('Error updating list:', error); + return; } - Lists.update(list._id, { - $set: updateData, - }); - boardComponent.setIsDragging(false); + + // Re-enable dragscroll after list dragging is complete + try { + dragscroll.reset(); + } catch (e) { + } + + // Re-enable dragscroll on all swimlanes + $('.js-swimlane').each(function() { + $(this).addClass('dragscroll'); + }); }, }); + } catch (error) { + console.error('Error initializing list sortable:', error); + return; + } + + + // Check if drag handles exist + const dragHandles = $listsDom.find('.js-list-handle'); + + // Check if lists exist + const lists = $listsDom.find('.js-list'); - boardComponent.autorun(() => { - if (Utils.isTouchScreenOrShowDesktopDragHandles()) { - $listsDom.sortable({ - handle: '.js-list-handle', - connectWith: '.js-swimlane, .js-lists', - }); - } else { - $listsDom.sortable({ - handle: '.js-list-header', - connectWith: '.js-swimlane, .js-lists', - }); - } - - const $listDom = $listsDom; - if ($listDom.data('uiSortable') || $listDom.data('sortable')) { - $listsDom.sortable( - 'option', - 'disabled', - !ReactiveCache.getCurrentUser()?.isBoardAdmin(), - ); - } - }); + // Skip the complex autorun and options for now } BlazeComponent.extendComponent({ onRendered() { const boardComponent = this.parentComponent(); const $listsDom = this.$('.js-lists'); + if (!Utils.getCurrentCardId()) { boardComponent.scrollLeft(); } - initSortable(boardComponent, $listsDom); + // Try a simpler approach - initialize sortable directly like cards do + + // Wait for DOM to be ready + setTimeout(() => { + const $lists = this.$('.js-list'); + + const $parent = $lists.parent(); + + if ($lists.length > 0) { + + // Check for drag handles + const $handles = $parent.find('.js-list-handle'); + + // Test if drag handles are clickable + $handles.on('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + }); + + $parent.sortable({ + connectWith: '.js-swimlane, .js-lists', + tolerance: 'pointer', + appendTo: '.board-canvas', + helper: 'clone', + items: '.js-list:not(.js-list-composer)', + placeholder: 'list placeholder', + distance: 7, + handle: '.js-list-handle', + disabled: !Utils.canModifyBoard(), + start(evt, ui) { + ui.helper.css('z-index', 1000); + ui.placeholder.height(ui.helper.height()); + ui.placeholder.width(ui.helper.width()); + EscapeActions.executeUpTo('popup-close'); + boardComponent.setIsDragging(true); + }, + stop(evt, ui) { + boardComponent.setIsDragging(false); + } + }); + } else { + } + }, 100); }, onCreated() { this.draggingActive = new ReactiveVar(false); @@ -223,10 +351,9 @@ BlazeComponent.extendComponent({ } } if (Filter.hideEmpty.isSelected()) { - const swimlaneId = this.parentComponent() - .parentComponent() - .data()._id; - const cards = list.cards(swimlaneId); + // Check for cards in all swimlanes, not just the current one + // This ensures lists with cards in other swimlanes are still visible + const cards = list.cards(); if (cards.length === 0) { return false; } @@ -248,10 +375,20 @@ BlazeComponent.extendComponent({ Utils.isTouchScreenOrShowDesktopDragHandles() ? ['.js-list-handle', '.js-swimlane-header-handle'] : ['.js-list-header'], - ); + ).concat([ + '.js-list-resize-handle', + '.js-swimlane-resize-handle' + ]); + const isResizeHandle = $(evt.target).closest('.js-list-resize-handle, .js-swimlane-resize-handle').length > 0; + const isInNoDragArea = $(evt.target).closest(noDragInside.join(',')).length > 0; + + if (isResizeHandle) { + return; + } + if ( - $(evt.target).closest(noDragInside.join(',')).length === 0 && + !isInNoDragArea && this.$('.swimlane').prop('clientHeight') > evt.offsetY ) { this._isDragging = true; @@ -284,11 +421,198 @@ BlazeComponent.extendComponent({ swimlaneHeight() { const user = ReactiveCache.getCurrentUser(); const swimlane = Template.currentData(); - const height = user.getSwimlaneHeight(swimlane.boardId, swimlane._id); + + let height; + if (user) { + // For logged-in users, get from user profile + height = user.getSwimlaneHeightFromStorage(swimlane.boardId, swimlane._id); + } else { + // For non-logged-in users, get from localStorage + try { + const stored = localStorage.getItem('wekan-swimlane-heights'); + if (stored) { + const heights = JSON.parse(stored); + if (heights[swimlane.boardId] && heights[swimlane.boardId][swimlane._id]) { + height = heights[swimlane.boardId][swimlane._id]; + } else { + height = -1; + } + } else { + height = -1; + } + } catch (e) { + console.warn('Error reading swimlane height from localStorage:', e); + height = -1; + } + } + return height == -1 ? "auto" : (height + 5 + "px"); }, + + onRendered() { + // Initialize swimlane resize functionality immediately + this.initializeSwimlaneResize(); + }, + + initializeSwimlaneResize() { + // Check if we're still in a valid template context + if (!Template.currentData()) { + console.warn('No current template data available for swimlane resize initialization'); + return; + } + + const swimlane = Template.currentData(); + const $swimlane = $(`#swimlane-${swimlane._id}`); + const $resizeHandle = $swimlane.find('.js-swimlane-resize-handle'); + + // Check if elements exist + if (!$swimlane.length || !$resizeHandle.length) { + console.warn('Swimlane or resize handle not found, retrying in 100ms'); + Meteor.setTimeout(() => { + if (!this.isDestroyed) { + this.initializeSwimlaneResize(); + } + }, 100); + return; + } + + + if ($resizeHandle.length === 0) { + return; + } + + let isResizing = false; + let startY = 0; + let startHeight = 0; + const minHeight = 100; + const maxHeight = 2000; + + const startResize = (e) => { + isResizing = true; + startY = e.pageY || e.originalEvent.touches[0].pageY; + startHeight = parseInt($swimlane.css('height')) || 300; + + + $swimlane.addClass('swimlane-resizing'); + $('body').addClass('swimlane-resizing-active'); + $('body').css('user-select', 'none'); + + + e.preventDefault(); + e.stopPropagation(); + }; + + const doResize = (e) => { + if (!isResizing) { + return; + } + + const currentY = e.pageY || e.originalEvent.touches[0].pageY; + const deltaY = currentY - startY; + const newHeight = Math.max(minHeight, Math.min(maxHeight, startHeight + deltaY)); + + + // Apply the new height immediately for real-time feedback + $swimlane[0].style.setProperty('--swimlane-height', `${newHeight}px`); + $swimlane[0].style.setProperty('height', `${newHeight}px`); + $swimlane[0].style.setProperty('min-height', `${newHeight}px`); + $swimlane[0].style.setProperty('max-height', `${newHeight}px`); + $swimlane[0].style.setProperty('flex', 'none'); + $swimlane[0].style.setProperty('flex-basis', 'auto'); + $swimlane[0].style.setProperty('flex-grow', '0'); + $swimlane[0].style.setProperty('flex-shrink', '0'); + + + e.preventDefault(); + e.stopPropagation(); + }; + + const stopResize = (e) => { + if (!isResizing) return; + + isResizing = false; + + // Calculate final height + const currentY = e.pageY || e.originalEvent.touches[0].pageY; + const deltaY = currentY - startY; + const finalHeight = Math.max(minHeight, Math.min(maxHeight, startHeight + deltaY)); + + // Ensure the final height is applied + $swimlane[0].style.setProperty('--swimlane-height', `${finalHeight}px`); + $swimlane[0].style.setProperty('height', `${finalHeight}px`); + $swimlane[0].style.setProperty('min-height', `${finalHeight}px`); + $swimlane[0].style.setProperty('max-height', `${finalHeight}px`); + $swimlane[0].style.setProperty('flex', 'none'); + $swimlane[0].style.setProperty('flex-basis', 'auto'); + $swimlane[0].style.setProperty('flex-grow', '0'); + $swimlane[0].style.setProperty('flex-shrink', '0'); + + // Remove visual feedback but keep the height + $swimlane.removeClass('swimlane-resizing'); + $('body').removeClass('swimlane-resizing-active'); + $('body').css('user-select', ''); + + // Save the new height using the existing system + const boardId = swimlane.boardId; + const swimlaneId = swimlane._id; + + if (process.env.DEBUG === 'true') { + } + + const currentUser = ReactiveCache.getCurrentUser(); + if (currentUser) { + // For logged-in users, use server method + Meteor.call('applySwimlaneHeightToStorage', boardId, swimlaneId, finalHeight, (error, result) => { + if (error) { + console.error('Error saving swimlane height:', error); + } else { + if (process.env.DEBUG === 'true') { + } + } + }); + } else { + // For non-logged-in users, save to localStorage directly + try { + const stored = localStorage.getItem('wekan-swimlane-heights'); + let heights = stored ? JSON.parse(stored) : {}; + + if (!heights[boardId]) { + heights[boardId] = {}; + } + heights[boardId][swimlaneId] = finalHeight; + + localStorage.setItem('wekan-swimlane-heights', JSON.stringify(heights)); + + if (process.env.DEBUG === 'true') { + } + } catch (e) { + console.warn('Error saving swimlane height to localStorage:', e); + } + } + + e.preventDefault(); + }; + + // Mouse events + $resizeHandle.on('mousedown', startResize); + $(document).on('mousemove', doResize); + $(document).on('mouseup', stopResize); + + // Touch events for mobile + $resizeHandle.on('touchstart', startResize, { passive: false }); + $(document).on('touchmove', doResize, { passive: false }); + $(document).on('touchend', stopResize, { passive: false }); + + + // Prevent dragscroll interference + $resizeHandle.on('mousedown', (e) => { + e.stopPropagation(); + }); + + }, }).register('swimlane'); + BlazeComponent.extendComponent({ onCreated() { this.currentBoard = Utils.getCurrentBoard(); @@ -356,8 +680,305 @@ Template.swimlane.helpers({ canSeeAddList() { return ReactiveCache.getCurrentUser().isBoardAdmin(); }, + + lists() { + // Return per-swimlane lists for this swimlane + return this.myLists(); + } }); +// Initialize sortable on DOM elements +setTimeout(() => { + const $swimlaneElements = $('.swimlane'); + const $listsGroupElements = $('.list-group'); + + // Initialize sortable on ALL swimlane elements (even empty ones) + $swimlaneElements.each(function(index) { + const $swimlane = $(this); + const $lists = $swimlane.find('.js-list'); + + // Only initialize on swimlanes that have the .js-lists class (the container for lists) + if ($swimlane.hasClass('js-lists')) { + $swimlane.sortable({ + connectWith: '.js-swimlane, .js-lists', + tolerance: 'pointer', + appendTo: '.board-canvas', + helper: 'clone', + items: '.js-list:not(.js-list-composer)', + placeholder: 'list placeholder', + distance: 7, + handle: '.js-list-handle', + disabled: !Utils.canModifyBoard(), + start(evt, ui) { + ui.helper.css('z-index', 1000); + ui.placeholder.height(ui.helper.height()); + ui.placeholder.width(ui.helper.width()); + EscapeActions.executeUpTo('popup-close'); + // Try to get board component + try { + const boardComponent = BlazeComponent.getComponentForElement(ui.item[0]); + if (boardComponent && boardComponent.setIsDragging) { + boardComponent.setIsDragging(true); + } + } catch (e) { + // Silent fail + } + }, + stop(evt, ui) { + // To attribute the new index number, we need to get the DOM element + // of the previous and the following list -- if any. + const prevListDom = ui.item.prev('.js-list').get(0); + const nextListDom = ui.item.next('.js-list').get(0); + const sortIndex = calculateIndex(prevListDom, nextListDom, 1); + + const listDomElement = ui.item.get(0); + if (!listDomElement) { + return; + } + + let list; + try { + list = Blaze.getData(listDomElement); + } catch (error) { + return; + } + + if (!list) { + return; + } + + // Detect if the list was dropped in a different swimlane + const targetSwimlaneDom = ui.item.closest('.js-swimlane'); + let targetSwimlaneId = null; + + if (targetSwimlaneDom.length > 0) { + // List was dropped in a swimlane + try { + targetSwimlaneId = targetSwimlaneDom.attr('id').replace('swimlane-', ''); + } catch (error) { + return; + } + } else { + // List was dropped in lists view (not swimlanes view) + // In this case, assign to the default swimlane + const currentBoard = ReactiveCache.getBoard(Session.get('currentBoard')); + if (currentBoard) { + const defaultSwimlane = currentBoard.getDefaultSwimline(); + if (defaultSwimlane) { + targetSwimlaneId = defaultSwimlane._id; + } + } + } + + // Get the original swimlane ID of the list (handle backward compatibility) + const originalSwimlaneId = list.getEffectiveSwimlaneId ? list.getEffectiveSwimlaneId() : (list.swimlaneId || null); + + // Prepare update object + const updateData = { + sort: sortIndex.base, + }; + + // Check if the list was dropped in a different swimlane + const isDifferentSwimlane = targetSwimlaneId && targetSwimlaneId !== originalSwimlaneId; + + // If the list was dropped in a different swimlane, update the swimlaneId + if (isDifferentSwimlane) { + updateData.swimlaneId = targetSwimlaneId; + + // Move all cards in the list to the new swimlane + const cardsInList = ReactiveCache.getCards({ + listId: list._id, + archived: false + }); + + cardsInList.forEach(card => { + card.move(list.boardId, targetSwimlaneId, list._id); + }); + + // Don't cancel the sortable when moving to a different swimlane + // The DOM move should be allowed to complete + } + // Allow reordering within the same swimlane by not canceling the sortable + + try { + Lists.update(list._id, { + $set: updateData, + }); + } catch (error) { + return; + } + + // Try to get board component + try { + const boardComponent = BlazeComponent.getComponentForElement(ui.item[0]); + if (boardComponent && boardComponent.setIsDragging) { + boardComponent.setIsDragging(false); + } + } catch (e) { + // Silent fail + } + + // Re-enable dragscroll after list dragging is complete + try { + dragscroll.reset(); + } catch (e) { + // Silent fail + } + + // Re-enable dragscroll on all swimlanes + $('.js-swimlane').each(function() { + $(this).addClass('dragscroll'); + }); + } + }); + } + }); + + // Initialize sortable on ALL listsGroup elements (even empty ones) + $listsGroupElements.each(function(index) { + const $listsGroup = $(this); + const $lists = $listsGroup.find('.js-list'); + + // Only initialize on listsGroup elements that have the .js-lists class + if ($listsGroup.hasClass('js-lists')) { + $listsGroup.sortable({ + connectWith: '.js-swimlane, .js-lists', + tolerance: 'pointer', + appendTo: '.board-canvas', + helper: 'clone', + items: '.js-list:not(.js-list-composer)', + placeholder: 'list placeholder', + distance: 7, + handle: '.js-list-handle', + disabled: !Utils.canModifyBoard(), + start(evt, ui) { + ui.helper.css('z-index', 1000); + ui.placeholder.height(ui.helper.height()); + ui.placeholder.width(ui.helper.width()); + EscapeActions.executeUpTo('popup-close'); + // Try to get board component + try { + const boardComponent = BlazeComponent.getComponentForElement(ui.item[0]); + if (boardComponent && boardComponent.setIsDragging) { + boardComponent.setIsDragging(true); + } + } catch (e) { + // Silent fail + } + }, + stop(evt, ui) { + // To attribute the new index number, we need to get the DOM element + // of the previous and the following list -- if any. + const prevListDom = ui.item.prev('.js-list').get(0); + const nextListDom = ui.item.next('.js-list').get(0); + const sortIndex = calculateIndex(prevListDom, nextListDom, 1); + + const listDomElement = ui.item.get(0); + if (!listDomElement) { + return; + } + + let list; + try { + list = Blaze.getData(listDomElement); + } catch (error) { + return; + } + + if (!list) { + return; + } + + // Detect if the list was dropped in a different swimlane + const targetSwimlaneDom = ui.item.closest('.js-swimlane'); + let targetSwimlaneId = null; + + if (targetSwimlaneDom.length > 0) { + // List was dropped in a swimlane + try { + targetSwimlaneId = targetSwimlaneDom.attr('id').replace('swimlane-', ''); + } catch (error) { + return; + } + } else { + // List was dropped in lists view (not swimlanes view) + // In this case, assign to the default swimlane + const currentBoard = ReactiveCache.getBoard(Session.get('currentBoard')); + if (currentBoard) { + const defaultSwimlane = currentBoard.getDefaultSwimline(); + if (defaultSwimlane) { + targetSwimlaneId = defaultSwimlane._id; + } + } + } + + // Get the original swimlane ID of the list (handle backward compatibility) + const originalSwimlaneId = list.getEffectiveSwimlaneId ? list.getEffectiveSwimlaneId() : (list.swimlaneId || null); + + // Prepare update object + const updateData = { + sort: sortIndex.base, + }; + + // Check if the list was dropped in a different swimlane + const isDifferentSwimlane = targetSwimlaneId && targetSwimlaneId !== originalSwimlaneId; + + // If the list was dropped in a different swimlane, update the swimlaneId + if (isDifferentSwimlane) { + updateData.swimlaneId = targetSwimlaneId; + + // Move all cards in the list to the new swimlane + const cardsInList = ReactiveCache.getCards({ + listId: list._id, + archived: false + }); + + cardsInList.forEach(card => { + card.move(list.boardId, targetSwimlaneId, list._id); + }); + + // Don't cancel the sortable when moving to a different swimlane + // The DOM move should be allowed to complete + } + // Allow reordering within the same swimlane by not canceling the sortable + + try { + Lists.update(list._id, { + $set: updateData, + }); + } catch (error) { + return; + } + + // Try to get board component + try { + const boardComponent = BlazeComponent.getComponentForElement(ui.item[0]); + if (boardComponent && boardComponent.setIsDragging) { + boardComponent.setIsDragging(false); + } + } catch (e) { + // Silent fail + } + + // Re-enable dragscroll after list dragging is complete + try { + dragscroll.reset(); + } catch (e) { + // Silent fail + } + + // Re-enable dragscroll on all swimlanes + $('.js-swimlane').each(function() { + $(this).addClass('dragscroll'); + }); + } + }); + } + }); +}, 1000); + + + BlazeComponent.extendComponent({ currentCardIsInThisList(listId, swimlaneId) { return currentCardIsInThisList(listId, swimlaneId); @@ -375,10 +996,9 @@ BlazeComponent.extendComponent({ } } if (Filter.hideEmpty.isSelected()) { - const swimlaneId = this.parentComponent() - .parentComponent() - .data()._id; - const cards = list.cards(swimlaneId); + // Check for cards in all swimlanes, not just the current one + // This ensures lists with cards in other swimlanes are still visible + const cards = list.cards(); if (cards.length === 0) { return false; } @@ -388,15 +1008,59 @@ BlazeComponent.extendComponent({ onRendered() { const boardComponent = this.parentComponent(); const $listsDom = this.$('.js-lists'); + if (!Utils.getCurrentCardId()) { boardComponent.scrollLeft(); } - initSortable(boardComponent, $listsDom); + // Try a simpler approach for listsGroup too + + // Wait for DOM to be ready + setTimeout(() => { + const $lists = this.$('.js-list'); + + const $parent = $lists.parent(); + + if ($lists.length > 0) { + + // Check for drag handles + const $handles = $parent.find('.js-list-handle'); + + // Test if drag handles are clickable + $handles.on('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + }); + + $parent.sortable({ + connectWith: '.js-swimlane, .js-lists', + tolerance: 'pointer', + appendTo: '.board-canvas', + helper: 'clone', + items: '.js-list:not(.js-list-composer)', + placeholder: 'list placeholder', + distance: 7, + handle: '.js-list-handle', + disabled: !Utils.canModifyBoard(), + start(evt, ui) { + ui.helper.css('z-index', 1000); + ui.placeholder.height(ui.helper.height()); + ui.placeholder.width(ui.helper.width()); + EscapeActions.executeUpTo('popup-close'); + boardComponent.setIsDragging(true); + }, + stop(evt, ui) { + boardComponent.setIsDragging(false); + } + }); + } else { + } + }, 100); }, }).register('listsGroup'); + class MoveSwimlaneComponent extends BlazeComponent { serverMethod = 'moveSwimlane'; diff --git a/client/components/users/userAvatar.jade b/client/components/users/userAvatar.jade index e6c51ef5e..e00fc188f 100644 --- a/client/components/users/userAvatar.jade +++ b/client/components/users/userAvatar.jade @@ -1,7 +1,7 @@ template(name="userAvatar") a.member(class="js-{{#if assignee}}assignee{{else}}member{{/if}}" title="{{userData.profile.fullname}} ({{userData.username}}) {{_ memberType}}") if userData.profile.avatarUrl - img.avatar.avatar-image(src="{{userData.profile.avatarUrl}}") + img.avatar.avatar-image(src="{{avatarUrl}}") else +userAvatarInitials(userId=userData._id) @@ -13,7 +13,7 @@ template(name="userAvatar") if showEdit if $eq currentUser._id userData._id a.edit-avatar.js-change-avatar - i.fa.fa-pencil + | ✏️ template(name="userAvatarInitials") svg.avatar.avatar-initials(viewBox="0 0 {{viewPortWidth}} 15") @@ -32,7 +32,8 @@ template(name="boardOrgRow") td if currentUser.isBoardAdmin a.member.orgOrTeamMember.add-member.js-manage-board-removeOrg(title="{{_ 'remove-from-board'}}") - i.removeTeamFaMinus.fa.fa-minus + i.removeTeamFaMinus + | ➖ .divaddfaplusminus | {{_ 'remove-btn'}} @@ -45,7 +46,8 @@ template(name="boardTeamRow") td if currentUser.isBoardAdmin a.member.orgOrTeamMember.add-member.js-manage-board-removeTeam(title="{{_ 'remove-from-board'}}") - i.removeTeamFaMinus.fa.fa-minus + i.removeTeamFaMinus + | ➖ .divaddfaplusminus | {{_ 'remove-btn'}} @@ -85,10 +87,10 @@ template(name="changeAvatarPopup") each uploadedAvatars li: a.js-select-avatar .member - img.avatar.avatar-image(src="{{link}}?auth=false&brokenIsFine=true") + img.avatar.avatar-image(src="{{link}}") | {{_ 'uploaded-avatar'}} if isSelected - i.fa.fa-check + | ✅ p.sub-name unless isSelected a.js-delete-avatar {{_ 'delete'}} @@ -99,7 +101,7 @@ template(name="changeAvatarPopup") +userAvatarInitials(userId=currentUser._id) | {{_ 'initials' }} if noAvatarUrl - i.fa.fa-check + | ✅ p.sub-name {{_ 'default-avatar'}} input.hide.js-upload-avatar-input(accept="image/*;capture=camera" type="file") if Meteor.settings.public.avatarsUploadMaxSize @@ -110,7 +112,7 @@ template(name="changeAvatarPopup") br | {{_ 'invalid-file'}} button.full.js-upload-avatar - i.fa.fa-upload + | 📤 | {{_ 'upload-avatar'}} template(name="cardMemberPopup") diff --git a/client/components/users/userAvatar.js b/client/components/users/userAvatar.js index 98ebc901e..f2db90ee3 100644 --- a/client/components/users/userAvatar.js +++ b/client/components/users/userAvatar.js @@ -15,6 +15,21 @@ Template.userAvatar.helpers({ }); }, + avatarUrl() { + const user = ReactiveCache.getUser(this.userId, { fields: { profile: 1 } }); + const base = (user && user.profile && user.profile.avatarUrl) || ''; + if (!base) return ''; + // Append current boardId when available so public viewers can access avatars on public boards + try { + const boardId = Utils.getCurrentBoardId && Utils.getCurrentBoardId(); + if (boardId) { + const sep = base.includes('?') ? '&' : '?'; + return `${base}${sep}boardId=${encodeURIComponent(boardId)}`; + } + } catch (_) {} + return base; + }, + memberType() { const user = ReactiveCache.getUser(this.userId); return user && user.isBoardAdmin() ? 'admin' : 'normal'; @@ -179,7 +194,7 @@ BlazeComponent.extendComponent({ isSelected() { const userProfile = ReactiveCache.getCurrentUser().profile; const avatarUrl = userProfile && userProfile.avatarUrl; - const currentAvatarUrl = `${this.currentData().link()}?auth=false&brokenIsFine=true`; + const currentAvatarUrl = this.currentData().link(); return avatarUrl === currentAvatarUrl; }, @@ -220,7 +235,7 @@ BlazeComponent.extendComponent({ } }, 'click .js-select-avatar'() { - const avatarUrl = `${this.currentData().link()}?auth=false&brokenIsFine=true`; + const avatarUrl = this.currentData().link(); this.setAvatar(avatarUrl); }, 'click .js-select-initials'() { diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 14fa948d7..7ee64d138 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -15,78 +15,88 @@ template(name="memberMenuPopup") with currentUser li a.js-my-cards(href="{{pathFor 'my-cards'}}") - i.fa.fa-list + | 📋 | {{_ 'my-cards'}} li a.js-due-cards(href="{{pathFor 'due-cards'}}") - i.fa.fa-calendar + | 📅 | {{_ 'dueCards-title'}} li a.js-global-search(href="{{pathFor 'global-search'}}") - i.fa.fa-search + | 🔍 | {{_ 'globalSearch-title'}} li a(href="{{pathFor 'home'}}") - span.fa.fa-home + | 🏠 + | 🏠 | {{_ 'all-boards'}} li a(href="{{pathFor 'public'}}") - span.fa.fa-globe + | 🌐 | {{_ 'public'}} li a.board-header-btn.js-open-archived-board - i.fa.fa-archive + | 📦 span {{_ 'archives'}} + li + a.js-notifications-drawer-toggle + | 🔔 + | {{_ 'notifications'}} + if currentSetting.customHelpLinkUrl + li + a(href="{{currentSetting.customHelpLinkUrl}}", title="{{_ 'help'}}", target="_blank", rel="noopener noreferrer") + | ❓ + | {{_ 'help'}} unless currentUser.isWorker ul.pop-over-list li a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") - i.fa.fa-clone + | 📋 | {{_ 'templates'}} if currentUser.isAdmin li a.js-go-setting(href="{{pathFor 'setting'}}") - i.fa.fa-lock + | 🔒 | {{_ 'admin-panel'}} hr if isSameDomainNameSettingValue li a.js-invite-people - i.fa.fa-envelope + | ✉️ | {{_ 'invite-people'}} if isNotOAuth2AuthenticationMethod li a.js-edit-profile - i.fa.fa-user + | 👤 | {{_ 'edit-profile'}} li a.js-change-settings - i.fa.fa-cog + | ⚙️ | {{_ 'change-settings'}} li a.js-change-avatar - i.fa.fa-picture-o + | 🖼️ | {{_ 'edit-avatar'}} unless isSandstorm if isNotOAuth2AuthenticationMethod li a.js-change-password - i.fa.fa-key + | 🔑 | {{_ 'changePasswordPopup-title'}} li a.js-change-language - i.fa.fa-flag + | 🏁 | {{_ 'changeLanguagePopup-title'}} //li // a.js-support - // i.fa.fa-question-circle + // ❓-circle // | {{_ 'support'}} unless isSandstorm hr ul.pop-over-list li a.js-logout - i.fa.fa-sign-out + | 🚪 | {{_ 'log-out'}} template(name="invitePeoplePopup") @@ -157,9 +167,10 @@ template(name="changeLanguagePopup") each languages li(class="{{# if isCurrentLanguage}}active{{/if}}") a.js-set-language - = name + | {{languageFlag}} + | {{name}} if isCurrentLanguage - i.fa.fa-check + | ✅ template(name="changeSettingsPopup") ul.pop-over-list @@ -172,11 +183,11 @@ template(name="changeSettingsPopup") unless currentUser.isWorker li label.bold.clear - i.fa.fa-sort-numeric-asc + | 🔢 | {{_ 'show-cards-minimum-count'}} input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="-1") label.bold.clear - i.fa.fa-calendar + | 📅 | {{_ 'start-day-of-week'}} select#start-day-of-week.inline-input.left each day in weekDays startDayOfWeek diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index dd7d56b1d..5514a1127 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -62,6 +62,15 @@ Template.memberMenuPopup.helpers({ }); Template.memberMenuPopup.events({ + 'click .js-open-bookmarks'(e) { + e.preventDefault(); + if (Utils.isMiniScreen()) { + FlowRouter.go('bookmarks'); + Popup.back(); + } else { + Popup.open('bookmarksPopup')(e); + } + }, 'click .js-my-cards'() { Popup.back(); }, @@ -78,6 +87,9 @@ Template.memberMenuPopup.events({ 'click .js-change-password': Popup.open('changePassword'), 'click .js-change-language': Popup.open('changeLanguage'), 'click .js-support': Popup.open('support'), + 'click .js-notifications-drawer-toggle'() { + Session.set('showNotificationsDrawer', !Session.get('showNotificationsDrawer')); + }, 'click .js-logout'(event) { event.preventDefault(); @@ -282,6 +294,30 @@ Template.changeLanguagePopup.helpers({ isCurrentLanguage() { return this.tag === TAPi18n.getLanguage(); }, + + languageFlag() { + const flagMap = { + 'en': '🇺🇸', 'es': '🇪🇸', 'fr': '🇫🇷', 'de': '🇩🇪', 'it': '🇮🇹', 'pt': '🇵🇹', 'ru': '🇷🇺', + 'ja': '🇯🇵', 'ko': '🇰🇷', 'zh': '🇨🇳', 'ar': '🇸🇦', 'hi': '🇮🇳', 'th': '🇹🇭', 'vi': '🇻🇳', + 'tr': '🇹🇷', 'pl': '🇵🇱', 'nl': '🇳🇱', 'sv': '🇸🇪', 'da': '🇩🇰', 'no': '🇳🇴', 'fi': '🇫🇮', + 'cs': '🇨🇿', 'hu': '🇭🇺', 'ro': '🇷🇴', 'bg': '🇧🇬', 'hr': '🇭🇷', 'sk': '🇸🇰', 'sl': '🇸🇮', + 'et': '🇪🇪', 'lv': '🇱🇻', 'lt': '🇱🇹', 'el': '🇬🇷', 'he': '🇮🇱', 'uk': '🇺🇦', 'be': '🇧🇾', + 'ca': '🇪🇸', 'eu': '🇪🇸', 'gl': '🇪🇸', 'cy': '🇬🇧', 'ga': '🇮🇪', 'mt': '🇲🇹', 'is': '🇮🇸', + 'mk': '🇲🇰', 'sq': '🇦🇱', 'sr': '🇷🇸', 'bs': '🇧🇦', 'me': '🇲🇪', 'fa': '🇮🇷', 'ur': '🇵🇰', + 'bn': '🇧🇩', 'ta': '🇮🇳', 'te': '🇮🇳', 'ml': '🇮🇳', 'kn': '🇮🇳', 'gu': '🇮🇳', 'pa': '🇮🇳', + 'or': '🇮🇳', 'as': '🇮🇳', 'ne': '🇳🇵', 'si': '🇱🇰', 'my': '🇲🇲', 'km': '🇰🇭', 'lo': '🇱🇦', + 'ka': '🇬🇪', 'hy': '🇦🇲', 'az': '🇦🇿', 'kk': '🇰🇿', 'ky': '🇰🇬', 'uz': '🇺🇿', 'mn': '🇲🇳', + 'bo': '🇨🇳', 'dz': '🇧🇹', 'ug': '🇨🇳', 'ii': '🇨🇳', 'za': '🇨🇳', 'yue': '🇭🇰', 'zh-HK': '🇭🇰', + 'zh-TW': '🇹🇼', 'zh-CN': '🇨🇳', 'id': '🇮🇩', 'ms': '🇲🇾', 'tl': '🇵🇭', 'ceb': '🇵🇭', + 'haw': '🇺🇸', 'mi': '🇳🇿', 'sm': '🇼🇸', 'to': '🇹🇴', 'fj': '🇫🇯', 'ty': '🇵🇫', 'mg': '🇲🇬', + 'sw': '🇹🇿', 'am': '🇪🇹', 'om': '🇪🇹', 'so': '🇸🇴', 'ti': '🇪🇷', 'ha': '🇳🇬', 'yo': '🇳🇬', + 'ig': '🇳🇬', 'zu': '🇿🇦', 'xh': '🇿🇦', 'af': '🇿🇦', 'st': '🇿🇦', 'tn': '🇿🇦', 'ss': '🇿🇦', + 've': '🇿🇦', 'ts': '🇿🇦', 'nr': '🇿🇦', 'nso': '🇿🇦', 'wo': '🇸🇳', 'ff': '🇸🇳', 'dy': '🇲🇱', + 'bm': '🇲🇱', 'tw': '🇬🇭', 'ak': '🇬🇭', 'lg': '🇺🇬', 'rw': '🇷🇼', 'rn': '🇧🇮', 'ny': '🇲🇼', + 'sn': '🇿🇼', 'nd': '🇿🇼' + }; + return flagMap[this.tag] || '🌐'; + }, }); Template.changeLanguagePopup.events({ diff --git a/client/config/blazeHelpers.js b/client/config/blazeHelpers.js index 10e558b37..333913dfc 100644 --- a/client/config/blazeHelpers.js +++ b/client/config/blazeHelpers.js @@ -1,7 +1,26 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { Blaze } from 'meteor/blaze'; import { Session } from 'meteor/session'; -import moment from 'moment/min/moment-with-locales'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; Blaze.registerHelper('currentBoard', () => { const ret = Utils.getCurrentBoard(); @@ -46,14 +65,18 @@ Blaze.registerHelper('isTouchScreenOrShowDesktopDragHandles', () => Blaze.registerHelper('moment', (...args) => { args.pop(); // hash - const [date, format] = args; - return moment(date).format(format ?? 'LLLL'); + const [date, formatStr] = args; + return format(new Date(date), formatStr ?? 'LLLL'); }); Blaze.registerHelper('canModifyCard', () => Utils.canModifyCard(), ); +Blaze.registerHelper('canMoveCard', () => + Utils.canMoveCard(), +); + Blaze.registerHelper('canModifyBoard', () => Utils.canModifyBoard(), ); diff --git a/client/lib/attachmentMigrationManager.js b/client/lib/attachmentMigrationManager.js new file mode 100644 index 000000000..e84124612 --- /dev/null +++ b/client/lib/attachmentMigrationManager.js @@ -0,0 +1,230 @@ +/** + * Attachment Migration Manager + * Handles migration of attachments from old structure to new structure + * with UI feedback and spinners for unconverted attachments + */ + +import { ReactiveVar } from 'meteor/reactive-var'; +import { ReactiveCache } from '/imports/reactiveCache'; + +// Reactive variables for attachment migration progress +export const attachmentMigrationProgress = new ReactiveVar(0); +export const attachmentMigrationStatus = new ReactiveVar(''); +export const isMigratingAttachments = new ReactiveVar(false); +export const unconvertedAttachments = new ReactiveVar([]); + +// Global tracking of migrated boards (persistent across component reinitializations) +const globalMigratedBoards = new Set(); + +class AttachmentMigrationManager { + constructor() { + this.migrationCache = new Map(); // Cache migrated attachment IDs + this.migratedBoards = new Set(); // Track boards that have been migrated + } + + /** + * Check if an attachment needs migration + * @param {string} attachmentId - The attachment ID to check + * @returns {boolean} - True if attachment needs migration + */ + needsMigration(attachmentId) { + if (this.migrationCache.has(attachmentId)) { + return false; // Already migrated + } + + try { + const attachment = ReactiveCache.getAttachment(attachmentId); + if (!attachment) return false; + + // Check if attachment has old structure (no meta field or missing required fields) + return !attachment.meta || + !attachment.meta.cardId || + !attachment.meta.boardId || + !attachment.meta.listId; + } catch (error) { + console.error('Error checking if attachment needs migration:', error); + return false; + } + } + + /** + * Check if a board has been migrated + * @param {string} boardId - The board ID + * @returns {boolean} - True if board has been migrated + */ + isBoardMigrated(boardId) { + return globalMigratedBoards.has(boardId); + } + + /** + * Check if a board has been migrated (server-side check) + * @param {string} boardId - The board ID + * @returns {Promise} - True if board has been migrated + */ + async isBoardMigratedServer(boardId) { + return new Promise((resolve) => { + Meteor.call('attachmentMigration.isBoardMigrated', boardId, (error, result) => { + if (error) { + console.error('Error checking board migration status:', error); + resolve(false); + } else { + resolve(result); + } + }); + }); + } + + /** + * Get all unconverted attachments for a board + * @param {string} boardId - The board ID + * @returns {Array} - Array of unconverted attachments + */ + getUnconvertedAttachments(boardId) { + try { + const attachments = ReactiveCache.getAttachments({ + 'meta.boardId': boardId + }); + + return attachments.filter(attachment => this.needsMigration(attachment._id)); + } catch (error) { + console.error('Error getting unconverted attachments:', error); + return []; + } + } + + /** + * Start migration for attachments in a board + * @param {string} boardId - The board ID + */ + async startAttachmentMigration(boardId) { + if (isMigratingAttachments.get()) { + return; // Already migrating + } + + // Check if this board has already been migrated (client-side check first) + if (globalMigratedBoards.has(boardId)) { + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has already been migrated (client-side), skipping`); + } + return; + } + + // Double-check with server-side check + const serverMigrated = await this.isBoardMigratedServer(boardId); + if (serverMigrated) { + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has already been migrated (server-side), skipping`); + } + globalMigratedBoards.add(boardId); // Sync client-side tracking + return; + } + + isMigratingAttachments.set(true); + attachmentMigrationStatus.set('Starting attachment migration...'); + attachmentMigrationProgress.set(0); + + try { + const unconverted = this.getUnconvertedAttachments(boardId); + unconvertedAttachments.set(unconverted); + + if (unconverted.length === 0) { + attachmentMigrationStatus.set('All attachments are already migrated'); + attachmentMigrationProgress.set(100); + isMigratingAttachments.set(false); + globalMigratedBoards.add(boardId); // Mark board as migrated + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} has no attachments to migrate, marked as migrated`); + } + return; + } + + // Start server-side migration + Meteor.call('attachmentMigration.migrateBoardAttachments', boardId, (error, result) => { + if (error) { + console.error('Failed to start attachment migration:', error); + const errorMessage = error.message || error.reason || error.toString(); + attachmentMigrationStatus.set(`Migration failed: ${errorMessage}`); + isMigratingAttachments.set(false); + } else { + if (process.env.DEBUG === 'true') { + console.log('Attachment migration started for board:', boardId); + } + this.pollAttachmentMigrationProgress(boardId); + } + }); + + } catch (error) { + console.error('Error starting attachment migration:', error); + attachmentMigrationStatus.set(`Migration failed: ${error.message}`); + isMigratingAttachments.set(false); + } + } + + /** + * Poll for attachment migration progress + * @param {string} boardId - The board ID + */ + pollAttachmentMigrationProgress(boardId) { + const pollInterval = setInterval(() => { + Meteor.call('attachmentMigration.getProgress', boardId, (error, result) => { + if (error) { + console.error('Error getting migration progress:', error); + clearInterval(pollInterval); + isMigratingAttachments.set(false); + return; + } + + if (result) { + attachmentMigrationProgress.set(result.progress); + attachmentMigrationStatus.set(result.status); + unconvertedAttachments.set(result.unconvertedAttachments || []); + + // Stop polling if migration is complete + if (result.progress >= 100 || result.status === 'completed') { + clearInterval(pollInterval); + isMigratingAttachments.set(false); + this.migrationCache.clear(); // Clear cache to refresh data + globalMigratedBoards.add(boardId); // Mark board as migrated + if (process.env.DEBUG === 'true') { + console.log(`Board ${boardId} migration completed and marked as migrated`); + } + } + } + }); + }, 1000); + } + + /** + * Check if an attachment is currently being migrated + * @param {string} attachmentId - The attachment ID + * @returns {boolean} - True if attachment is being migrated + */ + isAttachmentBeingMigrated(attachmentId) { + const unconverted = unconvertedAttachments.get(); + return unconverted.some(attachment => attachment._id === attachmentId); + } + + /** + * Get migration status for an attachment + * @param {string} attachmentId - The attachment ID + * @returns {string} - Migration status ('migrated', 'migrating', 'unmigrated') + */ + getAttachmentMigrationStatus(attachmentId) { + if (this.migrationCache.has(attachmentId)) { + return 'migrated'; + } + + if (this.isAttachmentBeingMigrated(attachmentId)) { + return 'migrating'; + } + + return this.needsMigration(attachmentId) ? 'unmigrated' : 'migrated'; + } +} + +export const attachmentMigrationManager = new AttachmentMigrationManager(); + + + + + diff --git a/client/lib/boardConverter.js b/client/lib/boardConverter.js new file mode 100644 index 000000000..71bbe5622 --- /dev/null +++ b/client/lib/boardConverter.js @@ -0,0 +1,226 @@ +/** + * Board Conversion Service + * Handles conversion of boards from old database structure to new structure + * without running migrations that could cause downtime + */ + +import { ReactiveVar } from 'meteor/reactive-var'; +import { ReactiveCache } from '/imports/reactiveCache'; +import Lists from '/models/lists'; + +// Reactive variables for conversion progress +export const conversionProgress = new ReactiveVar(0); +export const conversionStatus = new ReactiveVar(''); +export const conversionEstimatedTime = new ReactiveVar(''); +export const isConverting = new ReactiveVar(false); + +// Global tracking of converted boards (persistent across component reinitializations) +const globalConvertedBoards = new Set(); + +class BoardConverter { + constructor() { + this.conversionCache = new Map(); // Cache converted board IDs + } + + /** + * Check if a board has been converted + * @param {string} boardId - The board ID + * @returns {boolean} - True if board has been converted + */ + isBoardConverted(boardId) { + return globalConvertedBoards.has(boardId); + } + + /** + * Check if a board needs conversion + * @param {string} boardId - The board ID to check + * @returns {boolean} - True if board needs conversion + */ + needsConversion(boardId) { + if (this.conversionCache.has(boardId)) { + return false; // Already converted + } + + try { + const board = ReactiveCache.getBoard(boardId); + if (!board) return false; + + // Check if any lists in this board don't have swimlaneId + const lists = ReactiveCache.getLists({ + boardId: boardId, + $or: [ + { swimlaneId: { $exists: false } }, + { swimlaneId: '' }, + { swimlaneId: null } + ] + }); + + return lists.length > 0; + } catch (error) { + console.error('Error checking if board needs conversion:', error); + return false; + } + } + + /** + * Convert a board from old structure to new structure + * @param {string} boardId - The board ID to convert + * @returns {Promise} - True if conversion was successful + */ + async convertBoard(boardId) { + // Check if board has already been converted + if (this.isBoardConverted(boardId)) { + console.log(`Board ${boardId} has already been converted, skipping`); + return true; + } + + if (this.conversionCache.has(boardId)) { + return true; // Already converted + } + + isConverting.set(true); + conversionProgress.set(0); + conversionStatus.set('Starting board conversion...'); + + try { + const board = ReactiveCache.getBoard(boardId); + if (!board) { + throw new Error('Board not found'); + } + + // Get the default swimlane for this board + const defaultSwimlane = board.getDefaultSwimline(); + if (!defaultSwimlane) { + throw new Error('No default swimlane found for board'); + } + + // Get all lists that need conversion + const listsToConvert = ReactiveCache.getLists({ + boardId: boardId, + $or: [ + { swimlaneId: { $exists: false } }, + { swimlaneId: '' }, + { swimlaneId: null } + ] + }); + + if (listsToConvert.length === 0) { + this.conversionCache.set(boardId, true); + globalConvertedBoards.add(boardId); // Mark board as converted + isConverting.set(false); + console.log(`Board ${boardId} has no lists to convert, marked as converted`); + return true; + } + + conversionStatus.set(`Converting ${listsToConvert.length} lists...`); + + const startTime = Date.now(); + const totalLists = listsToConvert.length; + let convertedLists = 0; + + // Convert lists in batches to avoid blocking the UI + const batchSize = 10; + for (let i = 0; i < listsToConvert.length; i += batchSize) { + const batch = listsToConvert.slice(i, i + batchSize); + + // Process batch + await this.processBatch(batch, defaultSwimlane._id); + + convertedLists += batch.length; + const progress = Math.round((convertedLists / totalLists) * 100); + conversionProgress.set(progress); + + // Calculate estimated time remaining + const elapsed = Date.now() - startTime; + const rate = convertedLists / elapsed; // lists per millisecond + const remaining = totalLists - convertedLists; + const estimatedMs = remaining / rate; + + conversionStatus.set(`Converting list ${convertedLists} of ${totalLists}...`); + conversionEstimatedTime.set(this.formatTime(estimatedMs)); + + // Allow UI to update + await new Promise(resolve => setTimeout(resolve, 10)); + } + + // Mark as converted + this.conversionCache.set(boardId, true); + globalConvertedBoards.add(boardId); // Mark board as converted + + conversionStatus.set('Board conversion completed!'); + conversionProgress.set(100); + console.log(`Board ${boardId} conversion completed and marked as converted`); + + // Clear status after a delay + setTimeout(() => { + isConverting.set(false); + conversionStatus.set(''); + conversionProgress.set(0); + conversionEstimatedTime.set(''); + }, 2000); + + return true; + + } catch (error) { + console.error('Error converting board:', error); + conversionStatus.set(`Conversion failed: ${error.message}`); + isConverting.set(false); + return false; + } + } + + /** + * Process a batch of lists for conversion + * @param {Array} batch - Array of lists to convert + * @param {string} defaultSwimlaneId - Default swimlane ID + */ + async processBatch(batch, defaultSwimlaneId) { + const updates = batch.map(list => ({ + _id: list._id, + swimlaneId: defaultSwimlaneId + })); + + // Update lists in batch + updates.forEach(update => { + Lists.update(update._id, { + $set: { swimlaneId: update.swimlaneId } + }); + }); + } + + /** + * Format time in milliseconds to human readable format + * @param {number} ms - Time in milliseconds + * @returns {string} - Formatted time string + */ + formatTime(ms) { + if (ms < 1000) { + return `${Math.round(ms)}ms`; + } + + const seconds = Math.floor(ms / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + + if (hours > 0) { + const remainingMinutes = minutes % 60; + const remainingSeconds = seconds % 60; + return `${hours}h ${remainingMinutes}m ${remainingSeconds}s`; + } else if (minutes > 0) { + const remainingSeconds = seconds % 60; + return `${minutes}m ${remainingSeconds}s`; + } else { + return `${seconds}s`; + } + } + + /** + * Clear conversion cache (useful for testing) + */ + clearCache() { + this.conversionCache.clear(); + } +} + +// Export singleton instance +export const boardConverter = new BoardConverter(); diff --git a/client/lib/boardMultiSelection.js b/client/lib/boardMultiSelection.js new file mode 100644 index 000000000..036c312b6 --- /dev/null +++ b/client/lib/boardMultiSelection.js @@ -0,0 +1,73 @@ +import { ReactiveCache } from '/imports/reactiveCache'; + +BoardMultiSelection = { + _selectedBoards: new ReactiveVar([]), + + _isActive: new ReactiveVar(false), + + reset() { + this._selectedBoards.set([]); + }, + + isActive() { + return this._isActive.get(); + }, + + count() { + return this._selectedBoards.get().length; + }, + + isEmpty() { + return this.count() === 0; + }, + + getSelectedBoardIds() { + return this._selectedBoards.get(); + }, + + activate() { + if (!this.isActive()) { + this._isActive.set(true); + Tracker.flush(); + } + }, + + disable() { + if (this.isActive()) { + this._isActive.set(false); + this.reset(); + } + }, + + add(boardIds) { + return this.toggle(boardIds, { add: true, remove: false }); + }, + + remove(boardIds) { + return this.toggle(boardIds, { add: false, remove: true }); + }, + + toogle(boardIds) { + return this.toggle(boardIds, { add: true, remove: true }); + }, + + toggle(boardIds, { add, remove } = {}) { + boardIds = _.isString(boardIds) ? [boardIds] : boardIds; + let selectedBoards = this._selectedBoards.get(); + + boardIds.forEach(boardId => { + const index = selectedBoards.indexOf(boardId); + if (index > -1 && remove) { + selectedBoards = selectedBoards.filter(id => id !== boardId); + } else if (index === -1 && add) { + selectedBoards.push(boardId); + } + }); + + this._selectedBoards.set(selectedBoards); + }, + + isSelected(boardId) { + return this._selectedBoards.get().includes(boardId); + }, +}; diff --git a/client/lib/cardSearch.js b/client/lib/cardSearch.js index 4803f815b..a143965cf 100644 --- a/client/lib/cardSearch.js +++ b/client/lib/cardSearch.js @@ -29,21 +29,86 @@ export class CardSearchPagedComponent extends BlazeComponent { const that = this; this.subscriptionCallbacks = { onReady() { - that.getResults(); - that.searching.set(false); - that.hasResults.set(true); - that.serverError.set(false); + if (process.env.DEBUG === 'true') { + console.log('Subscription ready, getting results...'); + console.log('Subscription ready - sessionId:', that.sessionId); + } + + // Wait for session data to be available (with timeout) + let waitCount = 0; + const maxWaitCount = 50; // 10 seconds max wait + + const waitForSessionData = () => { + waitCount++; + const sessionData = that.getSessionData(); + if (process.env.DEBUG === 'true') { + console.log('waitForSessionData - attempt', waitCount, 'session data:', sessionData); + } + + if (sessionData) { + const results = that.getResults(); + if (process.env.DEBUG === 'true') { + console.log('Search results count:', results ? results.length : 0); + } + + // If no results and this is a due cards search, try to retry + if ((!results || results.length === 0) && that.searchRetryCount !== undefined && that.searchRetryCount < that.maxRetries) { + if (process.env.DEBUG === 'true') { + console.log('No results found, retrying search...'); + } + that.searchRetryCount++; + Meteor.setTimeout(() => { + if (that.performSearch) { + that.performSearch(); + } + }, 500); + return; + } + + that.searching.set(false); + that.hasResults.set(true); + that.serverError.set(false); + } else if (waitCount < maxWaitCount) { + // Session data not available yet, wait a bit more + if (process.env.DEBUG === 'true') { + console.log('Session data not available yet, waiting... (attempt', waitCount, 'of', maxWaitCount, ')'); + } + Meteor.setTimeout(waitForSessionData, 200); + } else { + // Timeout reached, try fallback search + if (process.env.DEBUG === 'true') { + console.log('Timeout reached waiting for session data, trying fallback search'); + } + const results = that.getResults(); + if (process.env.DEBUG === 'true') { + console.log('Fallback search results count:', results ? results.length : 0); + } + + if (results && results.length > 0) { + that.searching.set(false); + that.hasResults.set(true); + that.serverError.set(false); + } else { + that.searching.set(false); + that.hasResults.set(false); + that.serverError.set(true); + } + } + }; + + // Start waiting for session data + Meteor.setTimeout(waitForSessionData, 100); }, onError(error) { + if (process.env.DEBUG === 'true') { + console.log('Subscription error:', error); + console.log('Error.reason:', error.reason); + console.log('Error.message:', error.message); + console.log('Error.stack:', error.stack); + } that.searching.set(false); that.hasResults.set(false); that.serverError.set(true); - // eslint-disable-next-line no-console - //console.log('Error.reason:', error.reason); - // eslint-disable-next-line no-console - //console.log('Error.message:', error.message); - // eslint-disable-next-line no-console - //console.log('Error.stack:', error.stack); }, }; } @@ -62,9 +127,28 @@ export class CardSearchPagedComponent extends BlazeComponent { } getSessionData(sessionId) { - return ReactiveCache.getSessionData({ - sessionId: sessionId || SessionData.getSessionId(), + const sessionIdToUse = sessionId || SessionData.getSessionId(); + if (process.env.DEBUG === 'true') { + console.log('getSessionData - looking for sessionId:', sessionIdToUse); + } + + // Try using the raw SessionData collection instead of ReactiveCache + const sessionData = SessionData.findOne({ + sessionId: sessionIdToUse, }); + if (process.env.DEBUG === 'true') { + console.log('getSessionData - found session data (raw):', sessionData); + } + + // Also try ReactiveCache for comparison + const reactiveSessionData = ReactiveCache.getSessionData({ + sessionId: sessionIdToUse, + }); + if (process.env.DEBUG === 'true') { + console.log('getSessionData - found session data (reactive):', reactiveSessionData); + } + + return sessionData || reactiveSessionData; } getResults() { @@ -72,33 +156,87 @@ export class CardSearchPagedComponent extends BlazeComponent { // console.log('getting results'); this.sessionData = this.getSessionData(); // eslint-disable-next-line no-console - console.log('session data:', this.sessionData); + if (process.env.DEBUG === 'true') { + console.log('getResults - sessionId:', this.sessionId); + console.log('getResults - session data:', this.sessionData); + } const cards = []; - this.sessionData.cards.forEach(cardId => { - cards.push(ReactiveCache.getCard(cardId)); - }); - this.queryErrors = this.sessionData.errors; + + if (this.sessionData && this.sessionData.cards) { + if (process.env.DEBUG === 'true') { + console.log('getResults - cards array length:', this.sessionData.cards.length); + } + this.sessionData.cards.forEach(cardId => { + const card = ReactiveCache.getCard(cardId); + if (process.env.DEBUG === 'true') { + console.log('getResults - card:', cardId, card); + } + cards.push(card); + }); + this.queryErrors = this.sessionData.errors || []; + } else { + if (process.env.DEBUG === 'true') { + console.log('getResults - no sessionData or no cards array, trying direct card search'); + } + // Fallback: try to get cards directly from the client-side collection + // Use a more efficient query with limit and sort + const selector = { + type: 'cardType-card', + dueAt: { $exists: true, $nin: [null, ''] } + }; + const options = { + sort: { dueAt: 1 }, // Sort by due date ascending (oldest first) + limit: 100 // Limit to 100 cards for performance + }; + const allCards = Cards.find(selector, options).fetch(); + if (process.env.DEBUG === 'true') { + console.log('getResults - direct card search found:', allCards ? allCards.length : 0, 'cards'); + } + + if (allCards && allCards.length > 0) { + allCards.forEach(card => { + if (card && card._id) { + cards.push(card); + } + }); + } + + this.queryErrors = []; + } if (this.queryErrors.length) { // console.log('queryErrors:', this.queryErrorMessages()); this.hasQueryErrors.set(true); // return null; } - this.debug.set(new QueryDebug(this.sessionData.debug)); - console.log('debug:', this.debug.get().get()); - console.log('debug.show():', this.debug.get().show()); - console.log('debug.showSelector():', this.debug.get().showSelector()); + this.debug.set(new QueryDebug(this.sessionData ? this.sessionData.debug : null)); + if (process.env.DEBUG === 'true') { + console.log('debug:', this.debug.get().get()); + console.log('debug.show():', this.debug.get().show()); + console.log('debug.showSelector():', this.debug.get().showSelector()); + } if (cards) { - this.totalHits = this.sessionData.totalHits; - this.resultsCount = cards.length; - this.resultsStart = this.sessionData.lastHit - this.resultsCount + 1; - this.resultsEnd = this.sessionData.lastHit; - this.resultsHeading.set(this.getResultsHeading()); - this.results.set(cards); - this.hasNextPage.set(this.sessionData.lastHit < this.sessionData.totalHits); - this.hasPreviousPage.set( - this.sessionData.lastHit - this.sessionData.resultsCount > 0, - ); + if (this.sessionData) { + this.totalHits = this.sessionData.totalHits || 0; + this.resultsCount = cards.length; + this.resultsStart = this.sessionData.lastHit - this.resultsCount + 1; + this.resultsEnd = this.sessionData.lastHit; + this.resultsHeading.set(this.getResultsHeading()); + this.results.set(cards); + this.hasNextPage.set(this.sessionData.lastHit < this.sessionData.totalHits); + this.hasPreviousPage.set( + this.sessionData.lastHit - this.sessionData.resultsCount > 0, + ); + } else { + this.totalHits = cards.length; + this.resultsCount = cards.length; + this.resultsStart = 1; + this.resultsEnd = cards.length; + this.resultsHeading.set(this.getResultsHeading()); + this.results.set(cards); + this.hasNextPage.set(false); + this.hasPreviousPage.set(false); + } return cards; } @@ -113,13 +251,29 @@ export class CardSearchPagedComponent extends BlazeComponent { } getSubscription(queryParams) { - return Meteor.subscribe( + if (process.env.DEBUG === 'true') { + console.log('Subscribing to globalSearch with:', { + sessionId: this.sessionId, + params: queryParams.params, + text: queryParams.text + }); + } + + // Subscribe to both globalSearch and sessionData + const globalSearchHandle = Meteor.subscribe( 'globalSearch', this.sessionId, queryParams.params, queryParams.text, this.subscriptionCallbacks, ); + + const sessionDataHandle = Meteor.subscribe('sessionData', this.sessionId); + if (process.env.DEBUG === 'true') { + console.log('Subscribed to sessionData with sessionId:', this.sessionId); + } + + return globalSearchHandle; } runGlobalSearch(queryParams) { diff --git a/client/lib/datepicker.js b/client/lib/datepicker.js index f298a752d..fa2ff8129 100644 --- a/client/lib/datepicker.js +++ b/client/lib/datepicker.js @@ -1,15 +1,27 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { TAPi18n } from '/imports/i18n'; -import moment from 'moment/min/moment-with-locales'; -// Helper function to replace HH with H for 24 hours format, because H allows also single-digit hours -function adjustedTimeFormat() { - return moment - .localeData() - .longDateFormat('LT'); +// Helper to check if a date is valid +function isValidDate(date) { + return date instanceof Date && !isNaN(date); } -// .replace(/HH/i, 'H'); +// Format date as YYYY-MM-DD +function formatDate(date) { + if (!isValidDate(date)) return ''; + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; +} + +// Format time as HH:mm +function formatTime(date) { + if (!isValidDate(date)) return ''; + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + return `${hours}:${minutes}`; +} export class DatePicker extends BlazeComponent { template() { @@ -19,7 +31,7 @@ export class DatePicker extends BlazeComponent { onCreated(defaultTime = '1970-01-01 08:00:00') { this.error = new ReactiveVar(''); this.card = this.data(); - this.date = new ReactiveVar(moment.invalid()); + this.date = new ReactiveVar(new Date('invalid')); this.defaultTime = defaultTime; } @@ -33,102 +45,90 @@ export class DatePicker extends BlazeComponent { } onRendered() { - const $picker = this.$('.js-datepicker') - .datepicker({ - todayHighlight: true, - todayBtn: 'linked', - language: TAPi18n.getLanguage(), - weekStart: this.startDayOfWeek(), - calendarWeeks: true, - }) - .on( - 'changeDate', - function(evt) { - this.find('#date').value = moment(evt.date).format('L'); - this.error.set(''); - const timeInput = this.find('#time'); - timeInput.focus(); - if (!timeInput.value && this.defaultTime) { - const currentHour = evt.date.getHours(); - const defaultMoment = moment( - currentHour > 0 ? evt.date : this.defaultTime, - ); // default to 8:00 am local time - timeInput.value = defaultMoment.format('LT'); - } - }.bind(this), - ); - - if (this.date.get().isValid()) { - $picker.datepicker('update', this.date.get().toDate()); + // Set initial values for native HTML inputs + if (isValidDate(this.date.get())) { + const dateInput = this.find('#date'); + const timeInput = this.find('#time'); + + if (dateInput) { + dateInput.value = formatDate(this.date.get()); + } + if (timeInput && !timeInput.value && this.defaultTime) { + const defaultDate = new Date(this.defaultTime); + timeInput.value = formatTime(defaultDate); + } else if (timeInput && isValidDate(this.date.get())) { + timeInput.value = formatTime(this.date.get()); + } } } showDate() { - if (this.date.get().isValid()) return this.date.get().format('L'); + if (isValidDate(this.date.get())) return formatDate(this.date.get()); return ''; } showTime() { - if (this.date.get().isValid()) return this.date.get().format('LT'); + if (isValidDate(this.date.get())) return formatTime(this.date.get()); return ''; } dateFormat() { - return moment.localeData().longDateFormat('L'); + return 'YYYY-MM-DD'; } timeFormat() { - return moment.localeData().longDateFormat('LT'); + return 'HH:mm'; } events() { return [ { - 'keyup .js-date-field'() { - // parse for localized date format in strict mode - const dateMoment = moment(this.find('#date').value, 'L', true); - if (dateMoment.isValid()) { - this.error.set(''); - this.$('.js-datepicker').datepicker('update', dateMoment.toDate()); + 'change .js-date-field'() { + // Native HTML date input validation + const dateValue = this.find('#date').value; + if (dateValue) { + // HTML date input format is always YYYY-MM-DD + const dateObj = new Date(dateValue + 'T12:00:00'); + if (isValidDate(dateObj)) { + this.error.set(''); + } else { + this.error.set('invalid-date'); + } } }, - 'keyup .js-time-field'() { - // parse for localized time format in strict mode - const dateMoment = moment( - this.find('#time').value, - adjustedTimeFormat(), - true, - ); - if (dateMoment.isValid()) { - this.error.set(''); + 'change .js-time-field'() { + // Native HTML time input validation + const timeValue = this.find('#time').value; + if (timeValue) { + // HTML time input format is always HH:mm + const timeObj = new Date(`1970-01-01T${timeValue}:00`); + if (isValidDate(timeObj)) { + this.error.set(''); + } else { + this.error.set('invalid-time'); + } } }, 'submit .edit-date'(evt) { evt.preventDefault(); - // if no time was given, init with 12:00 - const time = - evt.target.time.value || - moment(new Date().setHours(12, 0, 0)).format('LT'); - const newTime = moment(time, adjustedTimeFormat(), true); - const newDate = moment(evt.target.date.value, 'L', true); - const dateString = `${evt.target.date.value} ${time}`; - const newCompleteDate = moment( - dateString, - `L ${adjustedTimeFormat()}`, - true, - ); - if (!newTime.isValid()) { - this.error.set('invalid-time'); - evt.target.time.focus(); - } - if (!newDate.isValid()) { + const dateValue = evt.target.date.value; + const timeValue = evt.target.time.value || '12:00'; // Default to 12:00 if no time given + + if (!dateValue) { this.error.set('invalid-date'); evt.target.date.focus(); + return; } - if (newCompleteDate.isValid()) { - this._storeDate(newCompleteDate.toDate()); - Popup.back(); - } else if (!this.error) { + + // Combine date and time: HTML date input is YYYY-MM-DD, time input is HH:mm + const dateTimeString = `${dateValue}T${timeValue}:00`; + const newCompleteDate = new Date(dateTimeString); + + if (!isValidDate(newCompleteDate)) { this.error.set('invalid'); + return; } + + this._storeDate(newCompleteDate); + Popup.back(); }, 'click .js-delete-date'(evt) { evt.preventDefault(); diff --git a/client/lib/filter.js b/client/lib/filter.js index 66ed01a36..463bd4535 100644 --- a/client/lib/filter.js +++ b/client/lib/filter.js @@ -1,5 +1,24 @@ import { ReactiveCache } from '/imports/reactiveCache'; -import moment from 'moment/min/moment-with-locales'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; // Filtered view manager // We define local filter objects for each different type of field (SetFilter, @@ -30,7 +49,7 @@ class DateFilter { this.reset(); return; } - this._filter = { $lte: moment().toDate() }; + this._filter = { $lte: now() }; this._updateState('past'); } @@ -72,13 +91,8 @@ class DateFilter { return; } - var startDay = moment() - .startOf('day') - .toDate(), - endDay = moment() - .endOf('day') - .add(offset, 'day') - .toDate(); + var startDay = startOf(now(), 'day'), + endDay = endOf(add(now(), offset, 'day'), 'day'); if (offset >= 0) { this._filter = { $gte: startDay, $lte: endDay }; @@ -112,33 +126,21 @@ class DateFilter { const weekStartDay = currentUser ? currentUser.getStartDayOfWeek() : 1; if (week === 'this') { - // Moments are mutable so they must be cloned before modification - var WeekStart = moment() - .startOf('day') - .startOf('week') - .add(weekStartDay, 'days'); - var WeekEnd = WeekStart - .clone() - .add(6, 'days') - .endOf('day'); + // Create week start and end dates + var WeekStart = startOf(add(startOf(now(), 'week'), weekStartDay, 'days'), 'day'); + var WeekEnd = endOf(add(WeekStart, 6, 'days'), 'day'); this._updateState('thisweek'); } else if (week === 'next') { - // Moments are mutable so they must be cloned before modification - var WeekStart = moment() - .startOf('day') - .startOf('week') - .add(weekStartDay + 7, 'days'); - var WeekEnd = WeekStart - .clone() - .add(6, 'days') - .endOf('day'); + // Create next week start and end dates + var WeekStart = startOf(add(startOf(now(), 'week'), weekStartDay + 7, 'days'), 'day'); + var WeekEnd = endOf(add(WeekStart, 6, 'days'), 'day'); this._updateState('nextweek'); } - var startDate = WeekStart.toDate(); - var endDate = WeekEnd.toDate(); + var startDate = WeekStart; + var endDate = WeekEnd; if (offset >= 0) { this._filter = { $gte: startDate, $lte: endDate }; diff --git a/client/lib/fixDuplicateLists.js b/client/lib/fixDuplicateLists.js new file mode 100644 index 000000000..06faefbdc --- /dev/null +++ b/client/lib/fixDuplicateLists.js @@ -0,0 +1,94 @@ +import { Meteor } from 'meteor/meteor'; + +/** + * Client-side interface for fixing duplicate lists + */ +export const fixDuplicateLists = { + + /** + * Get a report of all boards with duplicate lists/swimlanes + */ + async getReport() { + try { + const result = await Meteor.callAsync('fixDuplicateLists.getReport'); + return result; + } catch (error) { + console.error('Error getting duplicate lists report:', error); + throw error; + } + }, + + /** + * Fix duplicate lists for a specific board + */ + async fixBoard(boardId) { + try { + const result = await Meteor.callAsync('fixDuplicateLists.fixBoard', boardId); + console.log(`Fixed duplicate lists for board ${boardId}:`, result); + return result; + } catch (error) { + console.error(`Error fixing board ${boardId}:`, error); + throw error; + } + }, + + /** + * Fix duplicate lists for all boards + */ + async fixAllBoards() { + try { + console.log('Starting fix for all boards...'); + const result = await Meteor.callAsync('fixDuplicateLists.fixAllBoards'); + console.log('Fix completed:', result); + return result; + } catch (error) { + console.error('Error fixing all boards:', error); + throw error; + } + }, + + /** + * Interactive fix with user confirmation + */ + async interactiveFix() { + try { + // Get report first + console.log('Getting duplicate lists report...'); + const report = await this.getReport(); + + if (report.boardsWithDuplicates === 0) { + console.log('No duplicate lists found!'); + return { message: 'No duplicate lists found!' }; + } + + console.log(`Found ${report.boardsWithDuplicates} boards with duplicate lists:`); + report.report.forEach(board => { + console.log(`- Board "${board.boardTitle}" (${board.boardId}): ${board.duplicateSwimlanes} duplicate swimlanes, ${board.duplicateLists} duplicate lists`); + }); + + // Ask for confirmation + const confirmed = confirm( + `Found ${report.boardsWithDuplicates} boards with duplicate lists. ` + + `This will fix ${report.report.reduce((sum, board) => sum + board.duplicateSwimlanes + board.duplicateLists, 0)} duplicates. ` + + 'Continue?' + ); + + if (!confirmed) { + return { message: 'Fix cancelled by user' }; + } + + // Perform the fix + const result = await this.fixAllBoards(); + return result; + } catch (error) { + console.error('Error in interactive fix:', error); + throw error; + } + } +}; + +// Make it available globally for console access +if (typeof window !== 'undefined') { + window.fixDuplicateLists = fixDuplicateLists; +} + diff --git a/client/lib/migrationManager.js b/client/lib/migrationManager.js new file mode 100644 index 000000000..19ea53f10 --- /dev/null +++ b/client/lib/migrationManager.js @@ -0,0 +1,815 @@ +/** + * Migration Manager + * Handles all database migrations as steps during board loading + * with detailed progress tracking and background persistence + */ + +import { ReactiveVar } from 'meteor/reactive-var'; +import { ReactiveCache } from '/imports/reactiveCache'; + +// Reactive variables for migration progress +export const migrationProgress = new ReactiveVar(0); +export const migrationStatus = new ReactiveVar(''); +export const migrationCurrentStep = new ReactiveVar(''); +export const migrationSteps = new ReactiveVar([]); +export const isMigrating = new ReactiveVar(false); +export const migrationEstimatedTime = new ReactiveVar(''); + +class MigrationManager { + constructor() { + this.migrationCache = new Map(); // Cache completed migrations + this.steps = this.initializeMigrationSteps(); + this.currentStepIndex = 0; + this.startTime = null; + } + + /** + * Initialize all migration steps with their details + */ + initializeMigrationSteps() { + return [ + { + id: 'board-background-color', + name: 'Board Background Colors', + description: 'Setting up board background colors', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-cardcounterlist-allowed', + name: 'Card Counter List Settings', + description: 'Adding card counter list permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-boardmemberlist-allowed', + name: 'Board Member List Settings', + description: 'Adding board member list permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'lowercase-board-permission', + name: 'Board Permission Standardization', + description: 'Converting board permissions to lowercase', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'change-attachments-type-for-non-images', + name: 'Attachment Type Standardization', + description: 'Updating attachment types for non-images', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'card-covers', + name: 'Card Covers System', + description: 'Setting up card cover functionality', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'use-css-class-for-boards-colors', + name: 'Board Color CSS Classes', + description: 'Converting board colors to CSS classes', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'denormalize-star-number-per-board', + name: 'Board Star Counts', + description: 'Calculating star counts per board', + weight: 3, + completed: false, + progress: 0 + }, + { + id: 'add-member-isactive-field', + name: 'Member Activity Status', + description: 'Adding member activity tracking', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'add-sort-checklists', + name: 'Checklist Sorting', + description: 'Adding sort order to checklists', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'add-swimlanes', + name: 'Swimlanes System', + description: 'Setting up swimlanes functionality', + weight: 4, + completed: false, + progress: 0 + }, + { + id: 'add-views', + name: 'Board Views', + description: 'Adding board view options', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'add-checklist-items', + name: 'Checklist Items', + description: 'Setting up checklist items system', + weight: 3, + completed: false, + progress: 0 + }, + { + id: 'add-card-types', + name: 'Card Types', + description: 'Adding card type functionality', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'add-custom-fields-to-cards', + name: 'Custom Fields', + description: 'Adding custom fields to cards', + weight: 3, + completed: false, + progress: 0 + }, + { + id: 'add-requester-field', + name: 'Requester Field', + description: 'Adding requester field to cards', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-assigner-field', + name: 'Assigner Field', + description: 'Adding assigner field to cards', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-parent-field-to-cards', + name: 'Card Parent Relationships', + description: 'Adding parent field to cards', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'add-subtasks-boards', + name: 'Subtasks Boards', + description: 'Setting up subtasks board functionality', + weight: 3, + completed: false, + progress: 0 + }, + { + id: 'add-subtasks-sort', + name: 'Subtasks Sorting', + description: 'Adding sort order to subtasks', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'add-subtasks-allowed', + name: 'Subtasks Permissions', + description: 'Adding subtasks permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-authenticationMethod', + name: 'Authentication Methods', + description: 'Adding authentication method tracking', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'remove-tag', + name: 'Remove Tag Field', + description: 'Removing deprecated tag field', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'remove-customFields-references-broken', + name: 'Fix Custom Fields References', + description: 'Fixing broken custom field references', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'add-product-name', + name: 'Product Name Settings', + description: 'Adding product name configuration', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-hide-logo', + name: 'Hide Logo Setting', + description: 'Adding hide logo option', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-hide-card-counter-list', + name: 'Hide Card Counter Setting', + description: 'Adding hide card counter option', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-hide-board-member-list', + name: 'Hide Board Member List Setting', + description: 'Adding hide board member list option', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-displayAuthenticationMethod', + name: 'Display Authentication Method', + description: 'Adding authentication method display option', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-defaultAuthenticationMethod', + name: 'Default Authentication Method', + description: 'Setting default authentication method', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-templates', + name: 'Board Templates', + description: 'Setting up board templates system', + weight: 3, + completed: false, + progress: 0 + }, + { + id: 'fix-circular-reference_', + name: 'Fix Circular References', + description: 'Fixing circular references in cards', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'mutate-boardIds-in-customfields', + name: 'Custom Fields Board IDs', + description: 'Updating board IDs in custom fields', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'add-missing-created-and-modified', + name: 'Missing Timestamps', + description: 'Adding missing created and modified timestamps', + weight: 4, + completed: false, + progress: 0 + }, + { + id: 'fix-incorrect-dates', + name: 'Fix Incorrect Dates', + description: 'Correcting incorrect date values', + weight: 3, + completed: false, + progress: 0 + }, + { + id: 'add-assignee', + name: 'Assignee Field', + description: 'Adding assignee field to cards', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-profile-showDesktopDragHandles', + name: 'Desktop Drag Handles', + description: 'Adding desktop drag handles preference', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-profile-hiddenMinicardLabelText', + name: 'Hidden Minicard Labels', + description: 'Adding hidden minicard label text preference', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-receiveddate-allowed', + name: 'Received Date Permissions', + description: 'Adding received date permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-startdate-allowed', + name: 'Start Date Permissions', + description: 'Adding start date permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-duedate-allowed', + name: 'Due Date Permissions', + description: 'Adding due date permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-enddate-allowed', + name: 'End Date Permissions', + description: 'Adding end date permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-members-allowed', + name: 'Members Permissions', + description: 'Adding members permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-assignee-allowed', + name: 'Assignee Permissions', + description: 'Adding assignee permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-labels-allowed', + name: 'Labels Permissions', + description: 'Adding labels permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-checklists-allowed', + name: 'Checklists Permissions', + description: 'Adding checklists permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-attachments-allowed', + name: 'Attachments Permissions', + description: 'Adding attachments permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-comments-allowed', + name: 'Comments Permissions', + description: 'Adding comments permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-assigned-by-allowed', + name: 'Assigned By Permissions', + description: 'Adding assigned by permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-requested-by-allowed', + name: 'Requested By Permissions', + description: 'Adding requested by permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-activities-allowed', + name: 'Activities Permissions', + description: 'Adding activities permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-description-title-allowed', + name: 'Description Title Permissions', + description: 'Adding description title permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-description-text-allowed', + name: 'Description Text Permissions', + description: 'Adding description text permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-description-text-allowed-on-minicard', + name: 'Minicard Description Permissions', + description: 'Adding minicard description permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-sort-field-to-boards', + name: 'Board Sort Field', + description: 'Adding sort field to boards', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'add-default-profile-view', + name: 'Default Profile View', + description: 'Setting default profile view', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-hide-logo-by-default', + name: 'Hide Logo Default', + description: 'Setting hide logo as default', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-hide-card-counter-list-by-default', + name: 'Hide Card Counter Default', + description: 'Setting hide card counter as default', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-hide-board-member-list-by-default', + name: 'Hide Board Member List Default', + description: 'Setting hide board member list as default', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'add-card-number-allowed', + name: 'Card Number Permissions', + description: 'Adding card number permissions', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'assign-boardwise-card-numbers', + name: 'Board Card Numbers', + description: 'Assigning board-wise card numbers', + weight: 3, + completed: false, + progress: 0 + }, + { + id: 'add-card-details-show-lists', + name: 'Card Details Show Lists', + description: 'Adding card details show lists option', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'migrate-attachments-collectionFS-to-ostrioFiles', + name: 'Migrate Attachments to Meteor-Files', + description: 'Migrating attachments from CollectionFS to Meteor-Files', + weight: 8, + completed: false, + progress: 0 + }, + { + id: 'migrate-avatars-collectionFS-to-ostrioFiles', + name: 'Migrate Avatars to Meteor-Files', + description: 'Migrating avatars from CollectionFS to Meteor-Files', + weight: 6, + completed: false, + progress: 0 + }, + { + id: 'migrate-attachment-drop-index-cardId', + name: 'Drop Attachment Index', + description: 'Dropping old attachment index', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'migrate-attachment-migration-fix-source-import', + name: 'Fix Attachment Source Import', + description: 'Fixing attachment source import field', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'attachment-cardCopy-fix-boardId-etc', + name: 'Fix Attachment Card Copy', + description: 'Fixing attachment card copy board IDs', + weight: 2, + completed: false, + progress: 0 + }, + { + id: 'remove-unused-planning-poker', + name: 'Remove Planning Poker', + description: 'Removing unused planning poker fields', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'remove-user-profile-hiddenSystemMessages', + name: 'Remove Hidden System Messages', + description: 'Removing hidden system messages field', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'remove-user-profile-hideCheckedItems', + name: 'Remove Hide Checked Items', + description: 'Removing hide checked items field', + weight: 1, + completed: false, + progress: 0 + }, + { + id: 'migrate-lists-to-per-swimlane', + name: 'Migrate Lists to Per-Swimlane', + description: 'Migrating lists to per-swimlane structure', + weight: 5, + completed: false, + progress: 0 + } + ]; + } + + /** + * Check if any migrations need to be run for a specific board + */ + needsMigration(boardId = null) { + if (boardId) { + // Check if specific board needs migration based on version + const board = ReactiveCache.getBoard(boardId); + return !board || !board.migrationVersion || board.migrationVersion < 1; + } + + // Check if any migration step is not completed (global migrations) + return this.steps.some(step => !step.completed); + } + + /** + * Get total weight of all migrations + */ + getTotalWeight() { + return this.steps.reduce((total, step) => total + step.weight, 0); + } + + /** + * Get completed weight + */ + getCompletedWeight() { + return this.steps.reduce((total, step) => { + return total + (step.completed ? step.weight : step.progress * step.weight / 100); + }, 0); + } + + /** + * Mark a board as migrated + */ + markBoardAsMigrated(boardId) { + try { + Meteor.call('boardMigration.markAsMigrated', boardId, 'full_board_migration', (error, result) => { + if (error) { + console.error('Failed to mark board as migrated:', error); + } else { + console.log('Board marked as migrated:', boardId); + } + }); + } catch (error) { + console.error('Error marking board as migrated:', error); + } + } + + /** + * Fix boards that are stuck in migration loop + */ + fixStuckBoards() { + try { + Meteor.call('boardMigration.fixStuckBoards', (error, result) => { + if (error) { + console.error('Failed to fix stuck boards:', error); + } else { + console.log('Fix stuck boards result:', result); + } + }); + } catch (error) { + console.error('Error fixing stuck boards:', error); + } + } + + /** + * Start migration process using cron system + */ + async startMigration() { + if (isMigrating.get()) { + return; // Already migrating + } + + isMigrating.set(true); + migrationSteps.set([...this.steps]); + this.startTime = Date.now(); + + try { + // Start server-side cron migrations + Meteor.call('cron.startAllMigrations', (error, result) => { + if (error) { + console.error('Failed to start cron migrations:', error); + migrationStatus.set(`Migration failed: ${error.message}`); + isMigrating.set(false); + } + }); + + // Poll for progress updates + this.pollCronMigrationProgress(); + + } catch (error) { + console.error('Migration failed:', error); + migrationStatus.set(`Migration failed: ${error.message}`); + isMigrating.set(false); + } + } + + /** + * Poll for cron migration progress updates + */ + pollCronMigrationProgress() { + const pollInterval = setInterval(() => { + Meteor.call('cron.getMigrationProgress', (error, result) => { + if (error) { + console.error('Failed to get cron migration progress:', error); + clearInterval(pollInterval); + return; + } + + if (result) { + migrationProgress.set(result.progress); + migrationStatus.set(result.status); + migrationCurrentStep.set(result.currentStep); + migrationSteps.set(result.steps); + isMigrating.set(result.isMigrating); + + // Update local steps + if (result.steps) { + this.steps = result.steps; + } + + // If migration is complete, stop polling + if (!result.isMigrating && result.progress === 100) { + clearInterval(pollInterval); + + // Clear status after delay + setTimeout(() => { + migrationStatus.set(''); + migrationProgress.set(0); + migrationEstimatedTime.set(''); + }, 3000); + } + } + }); + }, 1000); // Poll every second + } + + /** + * Run a single migration step + */ + async runMigrationStep(step) { + // Simulate migration progress + const steps = 10; + for (let i = 0; i <= steps; i++) { + step.progress = (i / steps) * 100; + this.updateProgress(); + + // Simulate work + await new Promise(resolve => setTimeout(resolve, 50)); + } + + // In a real implementation, this would call the actual migration + // For now, we'll simulate the migration + // Running migration step + } + + /** + * Update progress variables + */ + updateProgress() { + const totalWeight = this.getTotalWeight(); + const completedWeight = this.getCompletedWeight(); + const progress = Math.round((completedWeight / totalWeight) * 100); + + migrationProgress.set(progress); + migrationSteps.set([...this.steps]); + + // Calculate estimated time remaining + if (this.startTime && progress > 0) { + const elapsed = Date.now() - this.startTime; + const rate = progress / elapsed; // progress per millisecond + const remaining = 100 - progress; + const estimatedMs = remaining / rate; + migrationEstimatedTime.set(this.formatTime(estimatedMs)); + } + } + + /** + * Format time in milliseconds to human readable format + */ + formatTime(ms) { + if (ms < 1000) { + return `${Math.round(ms)}ms`; + } + + const seconds = Math.floor(ms / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + + if (hours > 0) { + const remainingMinutes = minutes % 60; + const remainingSeconds = seconds % 60; + return `${hours}h ${remainingMinutes}m ${remainingSeconds}s`; + } else if (minutes > 0) { + const remainingSeconds = seconds % 60; + return `${minutes}m ${remainingSeconds}s`; + } else { + return `${seconds}s`; + } + } + + /** + * Clear migration cache (for testing) + */ + clearCache() { + this.migrationCache.clear(); + this.steps.forEach(step => { + step.completed = false; + step.progress = 0; + }); + } +} + +// Export singleton instance +export const migrationManager = new MigrationManager(); diff --git a/client/lib/originalPositionHelpers.js b/client/lib/originalPositionHelpers.js new file mode 100644 index 000000000..cc1bbe755 --- /dev/null +++ b/client/lib/originalPositionHelpers.js @@ -0,0 +1,114 @@ +/** + * Helper functions for integrating original position tracking into existing Wekan templates + */ + +/** + * Add original position tracking to swimlane templates + */ +export function addOriginalPositionToSwimlane(swimlaneId) { + if (!swimlaneId) return; + + // Track original position when swimlane is created or first accessed + Meteor.call('positionHistory.trackSwimlane', swimlaneId, (error) => { + if (error) { + console.warn('Failed to track original position for swimlane:', error); + } + }); +} + +/** + * Add original position tracking to list templates + */ +export function addOriginalPositionToList(listId) { + if (!listId) return; + + // Track original position when list is created or first accessed + Meteor.call('positionHistory.trackList', listId, (error) => { + if (error) { + console.warn('Failed to track original position for list:', error); + } + }); +} + +/** + * Add original position tracking to card templates + */ +export function addOriginalPositionToCard(cardId) { + if (!cardId) return; + + // Track original position when card is created or first accessed + Meteor.call('positionHistory.trackCard', cardId, (error) => { + if (error) { + console.warn('Failed to track original position for card:', error); + } + }); +} + +/** + * Get original position description for display in templates + */ +export function getOriginalPositionDescription(entityId, entityType) { + return new Promise((resolve, reject) => { + const methodName = `positionHistory.get${entityType.charAt(0).toUpperCase() + entityType.slice(1)}Description`; + + Meteor.call(methodName, entityId, (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + }); +} + +/** + * Check if an entity has moved from its original position + */ +export function hasEntityMoved(entityId, entityType) { + return new Promise((resolve, reject) => { + const methodName = `positionHistory.has${entityType.charAt(0).toUpperCase() + entityType.slice(1)}Moved`; + + Meteor.call(methodName, entityId, (error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + }); +} + +/** + * Template helper for displaying original position info + */ +Template.registerHelper('originalPositionInfo', function(entityId, entityType) { + if (!entityId || !entityType) return null; + + const description = getOriginalPositionDescription(entityId, entityType); + const hasMoved = hasEntityMoved(entityId, entityType); + + return { + description: description, + hasMoved: hasMoved, + entityId: entityId, + entityType: entityType + }; +}); + +/** + * Template helper for checking if entity has moved + */ +Template.registerHelper('hasEntityMoved', function(entityId, entityType) { + if (!entityId || !entityType) return false; + + return hasEntityMoved(entityId, entityType); +}); + +/** + * Template helper for getting original position description + */ +Template.registerHelper('getOriginalPositionDescription', function(entityId, entityType) { + if (!entityId || !entityType) return 'No original position data'; + + return getOriginalPositionDescription(entityId, entityType); +}); diff --git a/client/lib/popup.js b/client/lib/popup.js index ab8ea8230..6825f7032 100644 --- a/client/lib/popup.js +++ b/client/lib/popup.js @@ -46,6 +46,8 @@ window.Popup = new (class { return; } else { $(previousOpenerElement).removeClass('is-active'); + // Clean up previous popup content to prevent mixing + self._cleanupPreviousPopupContent(); } } @@ -58,7 +60,12 @@ window.Popup = new (class { if (clickFromPopup(evt) && self._getTopStack()) { openerElement = self._getTopStack().openerElement; } else { - self._stack = []; + // For Member Settings sub-popups, always start fresh to avoid content mixing + if (popupName.includes('changeLanguage') || popupName.includes('changeAvatar') || + popupName.includes('editProfile') || popupName.includes('changePassword') || + popupName.includes('invitePeople') || popupName.includes('support')) { + self._stack = []; + } openerElement = evt.currentTarget; } $(openerElement).addClass('is-active'); @@ -94,6 +101,10 @@ window.Popup = new (class { // our internal dependency, and since we just changed the top element of // our internal stack, the popup will be updated with the new data. if (!self.isOpen()) { + if (!Template[popupName]) { + console.error('Template not found:', popupName); + return; + } self.current = Blaze.renderWithData( self.template, () => { @@ -169,6 +180,8 @@ window.Popup = new (class { $(openerElement).removeClass('is-active'); this._stack = []; + // Clean up popup content when closing + this._cleanupPreviousPopupContent(); } } @@ -182,6 +195,13 @@ window.Popup = new (class { return this._stack[this._stack.length - 1]; } + _cleanupPreviousPopupContent() { + // Force a re-render to ensure proper cleanup + if (this._dep) { + this._dep.changed(); + } + } + // We automatically calculate the popup offset from the reference element // position and dimensions. We also reactively use the window dimensions to // ensure that the popup is always visible on the screen. @@ -193,11 +213,55 @@ window.Popup = new (class { if (Utils.isMiniScreen()) return { left: 0, top: 0 }; const offset = $element.offset(); - const popupWidth = 300 + 15; - return { - left: Math.min(offset.left, $(window).width() - popupWidth), - top: offset.top + $element.outerHeight(), - }; + // Calculate actual popup width based on CSS: min(380px, 55vw) + const viewportWidth = $(window).width(); + const viewportHeight = $(window).height(); + const popupWidth = Math.min(380, viewportWidth * 0.55) + 15; // Add 15px for margin + + // Check if this is an admin panel edit popup + const isAdminEditPopup = $element.hasClass('edit-user') || + $element.hasClass('edit-org') || + $element.hasClass('edit-team'); + + if (isAdminEditPopup) { + // Center the popup horizontally and use full height + const centeredLeft = (viewportWidth - popupWidth) / 2; + + return { + left: Math.max(10, centeredLeft), // Ensure popup doesn't go off screen + top: 10, // Start from top with small margin + maxHeight: viewportHeight - 20, // Use full height minus small margins + }; + } + + // Calculate available height for popup + const popupTop = offset.top + $element.outerHeight(); + + // For language popup, don't use dynamic height to avoid overlapping board + const isLanguagePopup = $element.hasClass('js-change-language'); + let availableHeight, maxPopupHeight; + + if (isLanguagePopup) { + // For language popup, position content area below right vertical scrollbar + const availableHeight = viewportHeight - popupTop - 20; // 20px margin from bottom (near scrollbar) + const calculatedHeight = Math.min(availableHeight, viewportHeight * 0.5); // Max 50% of viewport + + return { + left: Math.min(offset.left, viewportWidth - popupWidth), + top: popupTop, + maxHeight: Math.max(calculatedHeight, 200), // Minimum 200px height + }; + } else { + // For other popups, use the dynamic height calculation + availableHeight = viewportHeight - popupTop - 20; // 20px margin from bottom + maxPopupHeight = Math.min(availableHeight, viewportHeight * 0.8); // Max 80% of viewport + + return { + left: Math.min(offset.left, viewportWidth - popupWidth), + top: popupTop, + maxHeight: Math.max(maxPopupHeight, 200), // Minimum 200px height + }; + } }; } diff --git a/client/lib/secureDOMPurify.js b/client/lib/secureDOMPurify.js index c4e352e87..323c3b6c0 100644 --- a/client/lib/secureDOMPurify.js +++ b/client/lib/secureDOMPurify.js @@ -3,43 +3,25 @@ import DOMPurify from 'dompurify'; // Centralized secure DOMPurify configuration to prevent XSS and CSS injection attacks export function getSecureDOMPurifyConfig() { return { - // Block dangerous elements that can cause XSS and CSS injection - FORBID_TAGS: [ - 'svg', 'defs', 'use', 'g', 'symbol', 'marker', 'pattern', 'mask', 'clipPath', - 'linearGradient', 'radialGradient', 'stop', 'animate', 'animateTransform', - 'animateMotion', 'set', 'switch', 'foreignObject', 'script', 'style', 'link', - 'meta', 'iframe', 'object', 'embed', 'applet', 'form', 'input', 'textarea', - 'select', 'option', 'button', 'label', 'fieldset', 'legend', 'frameset', - 'frame', 'noframes', 'base', 'basefont', 'isindex', 'dir', 'menu', 'menuitem' - ], - // Block dangerous attributes that can cause XSS and CSS injection - FORBID_ATTR: [ - 'xlink:href', 'href', 'onload', 'onerror', 'onclick', 'onmouseover', - 'onfocus', 'onblur', 'onchange', 'onsubmit', 'onreset', 'onselect', - 'onunload', 'onresize', 'onscroll', 'onkeydown', 'onkeyup', 'onkeypress', - 'onmousedown', 'onmouseup', 'onmouseover', 'onmouseout', 'onmousemove', - 'ondblclick', 'oncontextmenu', 'onwheel', 'ontouchstart', 'ontouchend', - 'ontouchmove', 'ontouchcancel', 'onabort', 'oncanplay', 'oncanplaythrough', - 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onloadeddata', - 'onloadedmetadata', 'onloadstart', 'onpause', 'onplay', 'onplaying', - 'onprogress', 'onratechange', 'onseeked', 'onseeking', 'onstalled', - 'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting', 'onbeforeunload', - 'onhashchange', 'onpagehide', 'onpageshow', 'onpopstate', 'onstorage', - 'onunload', 'style', 'class', 'id', 'data-*', 'aria-*' - ], - // Allow only safe image formats and protocols + // Allow common markdown elements including anchor tags + ALLOWED_TAGS: ['a', 'p', 'br', 'strong', 'em', 'u', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'img', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'hr', 'div', 'span', 's'], + // Allow safe attributes including href for anchor tags + ALLOWED_ATTR: ['href', 'title', 'alt', 'src', 'width', 'height', 'target', 'rel'], + // Allow safe protocols for links ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i, - // Remove dangerous protocols + // Allow unknown protocols but be cautious ALLOW_UNKNOWN_PROTOCOLS: false, - // Sanitize URLs to prevent malicious content loading + // Sanitize DOM for security SANITIZE_DOM: true, - // Remove dangerous elements completely - KEEP_CONTENT: false, - // Additional security measures - ADD_ATTR: [], + // Keep content but sanitize it + KEEP_CONTENT: true, + // Block dangerous elements that can cause XSS + FORBID_TAGS: ['script', 'style', 'iframe', 'object', 'embed', 'applet', 'svg', 'defs', 'use', 'g', 'symbol', 'marker', 'pattern', 'mask', 'clipPath', 'linearGradient', 'radialGradient', 'stop', 'animate', 'animateTransform', 'animateMotion', 'set', 'switch', 'foreignObject', 'link', 'meta', 'form', 'input', 'textarea', 'select', 'option', 'button', 'label', 'fieldset', 'legend', 'frameset', 'frame', 'noframes', 'base', 'basefont', 'isindex', 'dir', 'menu', 'menuitem'], + // Block dangerous attributes but allow safe href + FORBID_ATTR: ['xlink:href', 'onload', 'onerror', 'onclick', 'onmouseover', 'onfocus', 'onblur', 'onchange', 'onsubmit', 'onreset', 'onselect', 'onunload', 'onresize', 'onscroll', 'onkeydown', 'onkeyup', 'onkeypress', 'onmousedown', 'onmouseup', 'onmouseover', 'onmouseout', 'onmousemove', 'ondblclick', 'oncontextmenu', 'onwheel', 'ontouchstart', 'ontouchend', 'ontouchmove', 'ontouchcancel', 'onabort', 'oncanplay', 'oncanplaythrough', 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onpause', 'onplay', 'onplaying', 'onprogress', 'onratechange', 'onseeked', 'onseeking', 'onstalled', 'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting', 'onbeforeunload', 'onhashchange', 'onpagehide', 'onpageshow', 'onpopstate', 'onstorage', 'onunload', 'style', 'class', 'id', 'data-*', 'aria-*'], // Block data URIs that could contain malicious content ALLOW_DATA_ATTR: false, - // Custom hook to further sanitize content + // Custom hooks for additional security HOOKS: { uponSanitizeElement: function(node, data) { // Block any remaining dangerous elements @@ -51,14 +33,37 @@ export function getSecureDOMPurifyConfig() { return false; } - // Block img tags with SVG data URIs + // Block img tags with SVG data URIs that could contain malicious JavaScript if (node.tagName && node.tagName.toLowerCase() === 'img') { const src = node.getAttribute('src'); - if (src && (src.startsWith('data:image/svg') || src.endsWith('.svg'))) { - if (process.env.DEBUG === 'true') { - console.warn('Blocked potentially malicious SVG image:', src); + if (src) { + // Block all SVG data URIs to prevent XSS via embedded JavaScript + if (src.startsWith('data:image/svg') || src.endsWith('.svg')) { + if (process.env.DEBUG === 'true') { + console.warn('Blocked potentially malicious SVG image:', src); + } + return false; + } + + // Additional check for base64 encoded SVG with script tags + if (src.startsWith('data:image/svg+xml;base64,')) { + try { + const base64Content = src.split(',')[1]; + const decodedContent = atob(base64Content); + if (decodedContent.includes(' { + if (error) { + console.error('[setBoardView] Update failed:', error); + } else { + // Reload to apply the view change + Utils.reload(); + } + }); } else if (view === 'board-view-swimlanes') { window.localStorage.setItem('boardView', 'board-view-swimlanes'); //true Utils.reload(); @@ -433,10 +454,14 @@ Utils = { // we can easily debug with a small window of desktop browser. :-) isMiniScreen() { this.windowResizeDep.depend(); + // Also depend on mobile mode changes to make this reactive + Session.get('wekan-mobile-mode'); + // Show mobile view when: // 1. Screen width is 800px or less (matches CSS media queries) // 2. Mobile phones in portrait mode // 3. iPad in very small screens (≤ 600px) + // 4. All iPhone models by default (including largest models), but respect user preference const isSmallScreen = window.innerWidth <= 800; const isVerySmallScreen = window.innerWidth <= 600; const isPortrait = window.innerWidth < window.innerHeight || window.matchMedia("(orientation: portrait)").matches; @@ -445,13 +470,19 @@ Utils = { const isIPad = /iPad/i.test(navigator.userAgent); const isUbuntuTouch = /Ubuntu/i.test(navigator.userAgent); - // For iPhone: always show mobile view regardless of orientation - // For other mobile phones: show mobile view in portrait, desktop view in landscape - // For iPad: show mobile view only in very small screens (≤ 600px) - // For Ubuntu Touch: smartphones behave like mobile phones, tablets like iPad - // For desktop: show mobile view when screen width <= 800px + // Check if user has explicitly set mobile mode preference + const userMobileMode = this.getMobileMode(); + + // For iPhone: default to mobile view, but respect user's mobile mode toggle preference + // This ensures all iPhone models (including iPhone 15 Pro Max, 14 Pro Max, etc.) start with mobile view + // but users can still switch to desktop mode if they prefer if (isIPhone) { - return true; // iPhone: always mobile view + // If user has explicitly set a preference, respect it + if (userMobileMode !== null && userMobileMode !== undefined) { + return userMobileMode; + } + // Otherwise, default to mobile view for iPhones + return true; } else if (isMobilePhone) { return isPortrait; // Other mobile phones: portrait = mobile, landscape = desktop } else if (isIPad) { @@ -496,30 +527,14 @@ Utils = { // returns if desktop drag handles are enabled isShowDesktopDragHandles() { - if (this.isTouchScreen()) { - return true; - /* - const currentUser = ReactiveCache.getCurrentUser(); - if (currentUser) { - return (currentUser.profile || {}).showDesktopDragHandles; - } else if (window.localStorage.getItem('showDesktopDragHandles')) { - // - if (window.localStorage.getItem('showDesktopDragHandles')) { - return true; - } else { - return false; - */ - } else { - return false; - } + // Always show drag handles on all displays + return true; }, // returns if mini screen or desktop drag handles isTouchScreenOrShowDesktopDragHandles() { - // Always enable drag handles for mobile screens (touch devices) - return this.isTouchScreen() || this.isMiniScreen(); - //return this.isTouchScreen() || this.isShowDesktopDragHandles(); - //return this.isShowDesktopDragHandles(); + // Always enable drag handles for all displays + return true; }, calculateIndexData(prevData, nextData, nItems = 1) { diff --git a/config/accounts.js b/config/accounts.js index 7a67a81b1..247627e97 100644 --- a/config/accounts.js +++ b/config/accounts.js @@ -1,6 +1,7 @@ import { TAPi18n } from '/imports/i18n'; const passwordField = AccountsTemplates.removeField('password'); +passwordField.autocomplete = 'current-password'; const emailField = AccountsTemplates.removeField('email'); let disableRegistration = false; let disableForgotPassword = false; @@ -61,6 +62,14 @@ AccountsTemplates.addFields([ }, emailField, passwordField, + { + _id: 'password_again', + type: 'password', + displayName: 'Password (again)', + required: true, + minLength: 6, + autocomplete: 'new-password', + }, { _id: 'invitationcode', type: 'text', diff --git a/config/query-classes.js b/config/query-classes.js index 4f0ef66a7..7ef4eb5fa 100644 --- a/config/query-classes.js +++ b/config/query-classes.js @@ -1,5 +1,24 @@ -import moment from 'moment/min/moment-with-locales'; import { TAPi18n } from '/imports/i18n'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; import { OPERATOR_ASSIGNEE, OPERATOR_BOARD, @@ -421,43 +440,44 @@ export class Query { switch (duration) { case PREDICATE_WEEK: // eslint-disable-next-line no-case-declarations - const week = moment().week(); + const week = getISOWeek(now()); if (week === 52) { - date = moment(1, 'W'); - date.set('year', date.year() + 1); + date = new Date(now().getFullYear() + 1, 0, 1); // January 1st of next year } else { - date = moment(week + 1, 'W'); + // Calculate the date for the next week + const currentDate = now(); + const daysToAdd = (week + 1) * 7 - (currentDate.getDay() + 6) % 7; + date = add(currentDate, daysToAdd, 'days'); } break; case PREDICATE_MONTH: // eslint-disable-next-line no-case-declarations - const month = moment().month(); - // .month() is zero indexed + const month = now().getMonth(); + // .getMonth() is zero indexed if (month === 11) { - date = moment(1, 'M'); - date.set('year', date.year() + 1); + date = new Date(now().getFullYear() + 1, 0, 1); // January 1st of next year } else { - date = moment(month + 2, 'M'); + date = new Date(now().getFullYear(), month + 1, 1); // First day of next month } break; case PREDICATE_QUARTER: // eslint-disable-next-line no-case-declarations - const quarter = moment().quarter(); + const quarter = Math.floor(now().getMonth() / 3) + 1; if (quarter === 4) { - date = moment(1, 'Q'); - date.set('year', date.year() + 1); + date = new Date(now().getFullYear() + 1, 0, 1); // January 1st of next year } else { - date = moment(quarter + 1, 'Q'); + const nextQuarterMonth = quarter * 3; // 3, 6, 9 for quarters 2, 3, 4 + date = new Date(now().getFullYear(), nextQuarterMonth, 1); // First day of next quarter } break; case PREDICATE_YEAR: - date = moment(moment().year() + 1, 'YYYY'); + date = new Date(now().getFullYear() + 1, 0, 1); // January 1st of next year break; } if (date) { value = { operator: '$lt', - value: date.format('YYYY-MM-DD'), + value: formatDate(date), }; } } else if ( @@ -466,7 +486,7 @@ export class Query { ) { value = { operator: '$lt', - value: moment().format('YYYY-MM-DD'), + value: formatDate(now()), }; } else { this.addError(OPERATOR_DUE, { @@ -478,16 +498,12 @@ export class Query { } else if (operator === OPERATOR_DUE) { value = { operator: '$lt', - value: moment(moment().format('YYYY-MM-DD')) - .add(days + 1, duration ? duration : 'days') - .format(), + value: formatDate(add(add(now(), 1, 'days'), days + 1, duration ? duration : 'days')), }; } else { value = { operator: '$gte', - value: moment(moment().format('YYYY-MM-DD')) - .subtract(days, duration ? duration : 'days') - .format(), + value: formatDate(subtract(now(), days, duration ? duration : 'days')), }; } } else if (operator === OPERATOR_SORT) { diff --git a/config/router.js b/config/router.js index 888393cfd..1ab853dbd 100644 --- a/config/router.js +++ b/config/router.js @@ -240,6 +240,25 @@ FlowRouter.route('/global-search', { }, }); +// Mobile Bookmarks page +FlowRouter.route('/bookmarks', { + name: 'bookmarks', + triggersEnter: [AccountsTemplates.ensureSignedIn], + action() { + Filter.reset(); + Session.set('sortBy', ''); + EscapeActions.executeUpTo('popup-close'); + + Utils.manageCustomUI(); + Utils.manageMatomo(); + + BlazeLayout.render('defaultLayout', { + headerBar: 'boardListHeaderBar', + content: 'bookmarks', + }); + }, +}); + FlowRouter.route('/broken-cards', { name: 'broken-cards', action() { diff --git a/docker-compose.yml b/docker-compose.yml index 8c9f44b6b..e41ce4e34 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -734,12 +734,13 @@ services: volumes: - /etc/localtime:/etc/localtime:ro - wekan-files:/data:rw - secrets: - - ldap_auth_password - - oauth2_secret - - mail_service_password - - mongo_password - - s3_secret + # Secrets are optional. Uncomment below and ensure files exist to use them. + #secrets: + # - ldap_auth_password + # - oauth2_secret + # - mail_service_password + # - mongo_password + # - s3_secret #--------------------------------------------------------------------------------- # ==== OPTIONAL: SHARE DATABASE TO OFFICE LAN AND REMOTE VPN ==== @@ -806,14 +807,15 @@ networks: # Create secret files on the host system before running docker-compose up # Example: echo "your_password_here" > ldap_auth_password.txt # Then use: docker-compose up -d -secrets: - ldap_auth_password: - file: ./secrets/ldap_auth_password.txt - oauth2_secret: - file: ./secrets/oauth2_secret.txt - mail_service_password: - file: ./secrets/mail_service_password.txt - mongo_password: - file: ./secrets/mongo_password.txt - s3_secret: - file: ./secrets/s3_secret.txt +# Secrets are optional. Uncomment to enable and ensure files exist at provided paths. +#secrets: +# ldap_auth_password: +# file: ./secrets/ldap_auth_password.txt +# oauth2_secret: +# file: ./secrets/oauth2_secret.txt +# mail_service_password: +# file: ./secrets/mail_service_password.txt +# mongo_password: +# file: ./secrets/mongo_password.txt +# s3_secret: +# file: ./secrets/s3_secret.txt diff --git a/docs/Design/Accessibility.md b/docs/Design/Accessibility.md new file mode 100644 index 000000000..c4caac759 --- /dev/null +++ b/docs/Design/Accessibility.md @@ -0,0 +1,236 @@ +# Wekan Accessibility & Responsive Design Improvements + +This document outlines the comprehensive accessibility and responsive design improvements implemented across all devices and screen sizes. + +## 🎯 Overview + +The improvements ensure Wekan is fully accessible and optimized for: +- **Smartphones** (320px - 767px) +- **Tablets** (768px - 1023px) +- **Laptops** (1024px - 1919px) +- **Desktops** (1920px - 2559px) +- **Large Displays** (2560px+) +- **Digital Signage & TV** (Ultra-wide and 4K+) + +## 📱 Mobile Optimizations + +### Touch Interactions +- **Minimum touch target size**: 44px × 44px (WCAG AA compliant) +- **Touch feedback**: Visual feedback for touch interactions +- **Prevent zoom on input focus**: Font size 16px prevents iOS zoom +- **Touch scrolling**: Smooth `-webkit-overflow-scrolling: touch` + +### Layout Improvements +- **Responsive typography**: `clamp(14px, 4vw, 18px)` scales with viewport +- **Flexible spacing**: `clamp(8px, 2vw, 16px)` for consistent spacing +- **Stacked navigation**: Header elements stack vertically on small screens +- **Full-width modals**: 95vw width for better mobile experience + +### Device-Specific Optimizations +- **iPhone 12 Mini**: 3x font scaling for readability +- **iPhone 12/13**: Optimized touch targets and spacing +- **iPhone Pro Max**: Enhanced layout for larger screens +- **Android phones**: Prevented zoom and improved touch handling + +## 📱 Tablet Optimizations + +### Touch-Friendly Design +- **Comfortable touch targets**: 48px × 48px minimum +- **Optimized spacing**: Balanced between mobile and desktop +- **Orientation support**: Different layouts for portrait/landscape + +### Layout Enhancements +- **Flexible grid**: Lists adapt to available space +- **Improved navigation**: Side menu optimized for touch +- **Modal sizing**: 80-90vw width for better tablet experience + +### Device-Specific Support +- **iPad (9th gen)**: 768×1024 optimization +- **iPad Air**: 810×1080 enhancement +- **iPad Pro 11"**: 834×1194 refinement +- **iPad Pro 12.9"**: 1024×1366 optimization +- **Android tablets**: Portrait and landscape modes + +## 💻 Desktop & Laptop Optimizations + +### Standard Desktop (1024px - 1919px) +- **Efficient use of space**: Optimal card and list sizing +- **Hover effects**: Enhanced interactivity for mouse users +- **Keyboard navigation**: Full keyboard accessibility +- **Modal sizing**: Standard 500px/800px widths + +### Large Displays (1920px+) +- **Scaled typography**: Larger fonts for better readability +- **Enhanced touch targets**: 56px+ for large displays +- **Centered layout**: Max-width containers prevent excessive stretching +- **Digital signage ready**: Optimized for TV and large displays + +### Ultra-Wide & 4K (2560px+) +- **Massive display support**: Up to 3200px max-width +- **Enhanced typography**: 20-22px base font size +- **Large touch targets**: 64px+ for digital signage +- **Print optimization**: Clean print layouts + +## ♿ Accessibility Features + +### Keyboard Navigation +- **Skip links**: Jump to main content and navigation +- **Tab order**: Logical tab sequence throughout the app +- **Arrow key navigation**: Navigate cards and lists with arrow keys +- **Escape key**: Close modals and popovers +- **Enter/Space**: Activate buttons and interactive elements + +### Screen Reader Support +- **ARIA labels**: Descriptive labels for all interactive elements +- **Live regions**: Announce state changes and updates +- **Role attributes**: Proper semantic roles for custom elements +- **Focus management**: Clear focus indicators and restoration + +### Visual Accessibility +- **High contrast mode**: Enhanced borders and colors +- **Focus indicators**: Clear 2px outline for keyboard users +- **Reduced motion**: Respects user motion preferences +- **Color independence**: Information not conveyed by color alone + +### Touch Accessibility +- **Large touch targets**: Minimum 44px for comfortable interaction +- **Touch feedback**: Visual confirmation of touch interactions +- **Gesture support**: Swipe and pinch gestures where appropriate +- **Prevent accidental touches**: Proper touch action handling + +## 🎨 Responsive Design Features + +### Fluid Typography +```css +font: clamp(14px, 2.5vw, 18px) Roboto, Poppins, "Helvetica Neue", Arial, Helvetica, sans-serif; +``` +- Scales smoothly between device sizes +- Maintains readability across all screens +- Uses system fonts for better performance + +### Flexible Spacing +```css +padding: clamp(8px, 2vw, 16px); +margin: clamp(12px, 1.5vw, 20px); +``` +- Consistent spacing that adapts to screen size +- Prevents cramped layouts on small screens +- Maintains proper proportions on large displays + +### Adaptive Layouts +- **Mobile**: Single column, stacked navigation +- **Tablet**: Flexible grid, touch-optimized +- **Desktop**: Multi-column, hover effects +- **Large displays**: Centered, max-width containers + +## 🔧 Technical Implementation + +### CSS Architecture +1. **Base styles**: `layouts.css` - Core typography and layout +2. **Responsive design**: `responsive-accessibility.css` - Cross-device compatibility +3. **Device-specific**: `device-specific.css` - Targeted optimizations +4. **Component styles**: Individual component CSS files + +### JavaScript Enhancements +1. **Accessibility**: `accessibility-enhancements.js` - ARIA, keyboard nav, screen readers +2. **Device detection**: Input method detection and device classification +3. **Focus management**: Focus trapping, restoration, and indicators +4. **Touch handling**: Touch feedback and gesture support + +### Viewport Configuration +```html + +``` +- Prevents horizontal scrolling +- Allows zoom up to 500% (WCAG AAA) +- Maintains usability at all zoom levels + +## 📊 Performance Optimizations + +### CSS Optimizations +- **Efficient selectors**: Minimal specificity conflicts +- **Hardware acceleration**: `transform` and `opacity` for animations +- **Reduced repaints**: Optimized layout properties +- **Critical CSS**: Above-the-fold styles prioritized + +### JavaScript Optimizations +- **Event delegation**: Efficient event handling +- **Debounced resize**: Optimized window resize handling +- **Lazy loading**: Dynamic content loading +- **Memory management**: Proper cleanup of event listeners + +## 🧪 Testing & Validation + +### Device Testing +- **Mobile**: iPhone 12 Mini, iPhone 13, Samsung Galaxy S21 +- **Tablet**: iPad (9th gen), iPad Air, iPad Pro, Samsung Tab S7 +- **Laptop**: MacBook Air, Dell XPS, HP Spectre +- **Desktop**: 1920×1080, 2560×1440, 3440×1440 ultrawide +- **Large displays**: 4K monitors, digital signage displays + +### Accessibility Testing +- **Screen readers**: NVDA, JAWS, VoiceOver +- **Keyboard navigation**: Tab, arrow keys, Enter, Escape +- **High contrast**: Windows and macOS high contrast modes +- **Zoom testing**: 200%, 300%, 400% zoom levels + +### Browser Support +- **Chrome**: 90+ (mobile and desktop) +- **Firefox**: 88+ (mobile and desktop) +- **Safari**: 14+ (iOS and macOS) +- **Edge**: 90+ (Windows and mobile) + +## 🚀 Usage Guidelines + +### For Developers +1. **Use semantic HTML**: Proper heading hierarchy and landmarks +2. **Include ARIA attributes**: Labels, roles, and states +3. **Test keyboard navigation**: Ensure all functionality is keyboard accessible +4. **Validate with screen readers**: Test with actual assistive technology + +### For Designers +1. **Maintain touch targets**: Minimum 44px for mobile, 48px+ for tablets +2. **Use sufficient contrast**: 4.5:1 for normal text, 3:1 for large text +3. **Design for motion sensitivity**: Provide reduced motion alternatives +4. **Test at different sizes**: Verify layouts work across all breakpoints + +### For Content Creators +1. **Use descriptive text**: Clear, concise labels and instructions +2. **Provide alt text**: Meaningful descriptions for images +3. **Structure content**: Use proper heading hierarchy +4. **Test with users**: Validate with actual users with disabilities + +## 📈 Future Enhancements + +### Planned Improvements +- **Voice control**: Voice navigation support +- **Eye tracking**: Eye tracking device compatibility +- **Haptic feedback**: Touch device vibration feedback +- **Advanced gestures**: Multi-touch gesture support + +### Monitoring & Analytics +- **Accessibility metrics**: Track accessibility usage patterns +- **Performance monitoring**: Monitor responsive design performance +- **User feedback**: Collect feedback on accessibility features +- **Continuous improvement**: Regular updates based on user needs + +## 📚 Resources + +### WCAG Guidelines +- [WCAG 2.1 AA Compliance](https://www.w3.org/WAI/WCAG21/quickref/) +- [Mobile Accessibility Guidelines](https://www.w3.org/WAI/mobile/) +- [Touch Target Guidelines](https://www.w3.org/WAI/WCAG21/Understanding/target-size.html) + +### Testing Tools +- [WAVE Web Accessibility Evaluator](https://wave.webaim.org/) +- [axe DevTools](https://www.deque.com/axe/devtools/) +- [Lighthouse Accessibility Audit](https://developers.google.com/web/tools/lighthouse) + +### Documentation +- [MDN Accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility) +- [WebAIM Resources](https://webaim.org/resources/) +- [A11y Project](https://www.a11yproject.com/) + +--- + +**Note**: This implementation ensures Wekan meets WCAG 2.1 AA standards and provides an excellent user experience across all devices and assistive technologies. diff --git a/docs/Design/Original-Positions.md b/docs/Design/Original-Positions.md new file mode 100644 index 000000000..358467307 --- /dev/null +++ b/docs/Design/Original-Positions.md @@ -0,0 +1,248 @@ +# Original Positions Tracking Feature + +This feature allows users to see the original positions of swimlanes, lists, and cards before the list naming feature was added in commit [719ef87efceacfe91461a8eeca7cf74d11f4cc0a](https://github.com/wekan/wekan/commit/719ef87efceacfe91461a8eeca7cf74d11f4cc0a). + +## Overview + +The original positions tracking system automatically captures and stores the initial positions of all board entities (swimlanes, lists, and cards) when they are created. This allows users to: + +- View the original position of any entity +- See if an entity has moved from its original position +- Track the original title before any changes +- View a complete history of original positions for a board + +## Features + +### 1. Automatic Position Tracking +- **Swimlanes**: Tracks original sort position and title +- **Lists**: Tracks original sort position, title, and swimlane assignment +- **Cards**: Tracks original sort position, title, swimlane, and list assignment + +### 2. Database Schema +The system uses a new `PositionHistory` collection with the following structure: +```javascript +{ + boardId: String, // Board ID + entityType: String, // 'swimlane', 'list', or 'card' + entityId: String, // Entity ID + originalPosition: Object, // Original position data + originalSwimlaneId: String, // Original swimlane (for lists/cards) + originalListId: String, // Original list (for cards) + originalTitle: String, // Original title + createdAt: Date, // When tracked + updatedAt: Date // Last updated +} +``` + +### 3. UI Components + +#### Individual Entity Display +- Shows original position information for individual swimlanes, lists, or cards +- Indicates if the entity has moved from its original position +- Displays original title if different from current title + +#### Board-Level View +- Complete overview of all original positions on a board +- Filter by entity type (swimlanes, lists, cards) +- Search and sort functionality +- Export capabilities + +## Usage + +### 1. Automatic Tracking +Position tracking happens automatically when entities are created. No manual intervention required. + +### 2. Viewing Original Positions + +#### In Templates +```html + +{{> originalPosition entityId=swimlane._id entityType="swimlane"}} + + +{{> originalPosition entityId=list._id entityType="list"}} + + +{{> originalPosition entityId=card._id entityType="card"}} +``` + +#### In JavaScript +```javascript +import { addOriginalPositionToSwimlane, addOriginalPositionToList, addOriginalPositionToCard } from '/client/lib/originalPositionHelpers'; + +// Track original position for a swimlane +addOriginalPositionToSwimlane(swimlaneId); + +// Track original position for a list +addOriginalPositionToList(listId); + +// Track original position for a card +addOriginalPositionToCard(cardId); +``` + +### 3. Server Methods + +#### Track Original Positions +```javascript +// Track swimlane +Meteor.call('positionHistory.trackSwimlane', swimlaneId); + +// Track list +Meteor.call('positionHistory.trackList', listId); + +// Track card +Meteor.call('positionHistory.trackCard', cardId); +``` + +#### Get Original Position Data +```javascript +// Get swimlane original position +Meteor.call('positionHistory.getSwimlaneOriginalPosition', swimlaneId); + +// Get list original position +Meteor.call('positionHistory.getListOriginalPosition', listId); + +// Get card original position +Meteor.call('positionHistory.getCardOriginalPosition', cardId); +``` + +#### Check if Entity Has Moved +```javascript +// Check if swimlane has moved +Meteor.call('positionHistory.hasSwimlaneMoved', swimlaneId); + +// Check if list has moved +Meteor.call('positionHistory.hasListMoved', listId); + +// Check if card has moved +Meteor.call('positionHistory.hasCardMoved', cardId); +``` + +#### Get Board History +```javascript +// Get all position history for a board +Meteor.call('positionHistory.getBoardHistory', boardId); + +// Get position history by entity type +Meteor.call('positionHistory.getBoardHistoryByType', boardId, 'swimlane'); +Meteor.call('positionHistory.getBoardHistoryByType', boardId, 'list'); +Meteor.call('positionHistory.getBoardHistoryByType', boardId, 'card'); +``` + +## Integration Examples + +### 1. Add to Swimlane Template +```html + +``` + +### 2. Add to List Template +```html + +``` + +### 3. Add to Card Template +```html + +``` + +### 4. Add Board-Level View +```html + +``` + +## Configuration + +### 1. Enable/Disable Tracking +Position tracking is enabled by default. To disable it, comment out the tracking hooks in the model files: + +```javascript +// In models/swimlanes.js, models/lists.js, models/cards.js +// Comment out the tracking hooks: +/* +Meteor.setTimeout(() => { + const entity = Collection.findOne(doc._id); + if (entity) { + entity.trackOriginalPosition(); + } +}, 100); +*/ +``` + +### 2. Customize Display +Modify the CSS files to customize the appearance: +- `client/components/common/originalPosition.css` +- `client/components/boards/originalPositionsView.css` + +## Database Migration + +No database migration is required. The system automatically creates the `PositionHistory` collection when first used. + +## Performance Considerations + +- Position tracking adds minimal overhead to entity creation +- Original position data is only stored once per entity +- Database indexes are created for efficient querying +- UI components use reactive data for real-time updates + +## Troubleshooting + +### 1. Original Position Not Showing +- Check if the entity has been created after the feature was implemented +- Verify that the position tracking hooks are enabled +- Check browser console for any JavaScript errors + +### 2. Performance Issues +- Ensure database indexes are created (happens automatically on startup) +- Consider limiting the number of entities displayed in the board view +- Use the filter functionality to reduce the number of displayed items + +### 3. Data Inconsistencies +- Original position data is only captured when entities are created +- Existing entities will not have original position data +- Use the refresh functionality to re-scan the board + +## Future Enhancements + +- Export original position data to CSV/JSON +- Bulk operations for managing original positions +- Integration with board templates +- Advanced filtering and search capabilities +- Position change notifications +- Historical position timeline view + +## Support + +For issues or questions about the original positions tracking feature, please: +1. Check the browser console for errors +2. Verify that all required files are present +3. Test with a new board to ensure the feature works correctly +4. Report issues with detailed error messages and steps to reproduce diff --git a/docs/Platforms/FOSS/Snap/Snap-build.md b/docs/Platforms/FOSS/Snap/Snap-build.md new file mode 100644 index 000000000..ee973115a --- /dev/null +++ b/docs/Platforms/FOSS/Snap/Snap-build.md @@ -0,0 +1,103 @@ +# Building the Wekan snap without timeouts + +This guide focuses on macOS hosts (Multipass VM) and common timeout fixes. It also applies to Linux hosts with LXD. + +## Quick options + +- Fastest: use Canonical builders (no local VM) + + ```zsh + # One-time: login to the store (required for remote-build) + snapcraft login + + # Build for amd64 on Canonical builders + snapcraft remote-build --build-for=amd64 + ``` + +- Local VM (macOS + Multipass): increase resources and build verbosely + + ```zsh + # Give the builder more CPU/RAM/disk to avoid sluggish downloads + export SNAPCRAFT_BUILD_ENVIRONMENT=hosted-multipass + export SNAPCRAFT_BUILD_ENVIRONMENT_CPU=4 + export SNAPCRAFT_BUILD_ENVIRONMENT_MEMORY=8G + export SNAPCRAFT_BUILD_ENVIRONMENT_DISK=40G + + # Clean previous state and build + snapcraft clean + snapcraft --verbose --debug + ``` + +## What changed to reduce timeouts + +- Downloads in `wekan` part now retry with exponential backoff. +- `caddy` part now attempts APT with retries and falls back to a static binary from the official GitHub release if APT is slow or unreachable. + +These changes make the build resilient to transient network issues and slow mirrors. + +## Diagnosing where it stalls + +- Run a single step for a part to reproduce: + ```zsh + snapcraft pull wekan -v + snapcraft build wekan -v + ``` +- Drop into the build environment when it fails: + ```zsh + snapcraft --debug + # Then run the failing commands manually + ``` + +## Tips for macOS + Multipass + +- Check networking: + ```zsh + multipass list + multipass exec snapcraft-*-wekan -- ping -c2 github.com + ``` +- If the instance looks wedged, recreate it: + ```zsh + snapcraft clean --use-lxd || true # harmless on macOS + snapcraft clean --step pull + multipass delete --purge $(multipass list | awk '/snapcraft-/{print $1}') + snapcraft --verbose + ``` + +## Linux hosts (optional) + +On Linux, using LXD is often faster and more reliable than Multipass: + +```bash +sudo snap install lxd --channel=5.21/stable +newgrp lxd +snapcraft --use-lxd -v +``` + +## Common environment knobs + +- Proxy/mirror environments inside the build VM if needed: + ```zsh + export http_proxy=http://proxy.example:3128 + export https_proxy=$http_proxy + export SNAPCRAFT_PROXY_HTTP=$http_proxy + export SNAPCRAFT_PROXY_HTTPS=$https_proxy + ``` + +- Speed up apt by pinning retries (already set in the recipe) or switching to a closer mirror by customizing sources in an override if needed. + +## Cleaning up caches + +If repeated attempts keep hitting corrupt downloads, clean Snapcraft caches: + +```zsh +snapcraft clean --destructive-mode || true +rm -rf ~/.cache/snapcraft/* +``` + +## Reporting + +If you still hit timeouts, capture and share: +- The exact step (pull/build/stage/prime) and part name +- Output of `snapcraft --verbose --debug` +- Host OS and Snapcraft version: `snapcraft --version` +- Multipass resources: `multipass list` diff --git a/docs/Platforms/Propietary/Windows/Offline.md b/docs/Platforms/Propietary/Windows/Offline.md index fd453eefb..4da341fd1 100644 --- a/docs/Platforms/Propietary/Windows/Offline.md +++ b/docs/Platforms/Propietary/Windows/Offline.md @@ -10,7 +10,7 @@ This is without container (without Docker or Snap). Right click and download files 1-4: -1. [wekan-8.01-amd64-windows.zip](https://github.com/wekan/wekan/releases/download/v8.01/wekan-8.01-amd64-windows.zip) +1. [wekan-8.17-amd64-windows.zip](https://github.com/wekan/wekan/releases/download/v8.17/wekan-8.17-amd64-windows.zip) 2. [node.exe](https://nodejs.org/dist/latest-v14.x/win-x64/node.exe) @@ -22,7 +22,7 @@ Right click and download files 1-4: 6. Double click `mongodb-windows-x86_64-7.0.25-signed.msi` . In installer, uncheck downloading MongoDB compass. -7. Unzip `wekan-8.01-amd64-windows.zip` , inside it is directory `bundle`, to it copy other files: +7. Unzip `wekan-8.17-amd64-windows.zip` , inside it is directory `bundle`, to it copy other files: ``` bundle (directory) diff --git a/imports/i18n/data/af.i18n.json b/imports/i18n/data/af.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/af.i18n.json +++ b/imports/i18n/data/af.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/af_ZA.i18n.json b/imports/i18n/data/af_ZA.i18n.json index 62827936c..d397f5944 100644 --- a/imports/i18n/data/af_ZA.i18n.json +++ b/imports/i18n/data/af_ZA.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ar-DZ.i18n.json b/imports/i18n/data/ar-DZ.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/ar-DZ.i18n.json +++ b/imports/i18n/data/ar-DZ.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ar-EG.i18n.json b/imports/i18n/data/ar-EG.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/ar-EG.i18n.json +++ b/imports/i18n/data/ar-EG.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ar.i18n.json b/imports/i18n/data/ar.i18n.json index 7c6718973..5ba52f954 100644 --- a/imports/i18n/data/ar.i18n.json +++ b/imports/i18n/data/ar.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "تعليق محذوف %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "نماذج", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "إضافة مرفق", @@ -190,7 +202,9 @@ "board-view-collapse": "انهيار", "board-view-gantt": "Gantt", "board-view-lists": "القائمات", - "bucket-example": "مثل « todo list » على سبيل المثال", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "إلغاء", "card-archived": "البطاقة منقولة الى الارشيف", "board-archived": "اللوحات منقولة الى الارشيف", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "إنشاء", "createBoardPopup-title": "إنشاء لوحة", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "استيراد لوحة", "createLabelPopup-title": "إنشاء علامة", "createCustomField": "انشاء حقل", @@ -354,6 +369,10 @@ "custom-field-text": "نص", "custom-fields": "Custom Fields", "date": "تاريخ", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "صورة شخصية افتراضية", "delete": "حذف", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "تصحيح الإشعار", "editProfilePopup-title": "تعديل الملف الشخصي", "email": "البريد الإلكتروني", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "انا", "dueCardsViewChange-choice-all": "كل المستخدمين", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "تفاصيل", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ary.i18n.json b/imports/i18n/data/ary.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/ary.i18n.json +++ b/imports/i18n/data/ary.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ast-ES.i18n.json b/imports/i18n/data/ast-ES.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/ast-ES.i18n.json +++ b/imports/i18n/data/ast-ES.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/az-AZ.i18n.json b/imports/i18n/data/az-AZ.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/az-AZ.i18n.json +++ b/imports/i18n/data/az-AZ.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/az-LA.i18n.json b/imports/i18n/data/az-LA.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/az-LA.i18n.json +++ b/imports/i18n/data/az-LA.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/az.i18n.json b/imports/i18n/data/az.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/az.i18n.json +++ b/imports/i18n/data/az.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/bg.i18n.json b/imports/i18n/data/bg.i18n.json index 89f045e90..f78534731 100644 --- a/imports/i18n/data/bg.i18n.json +++ b/imports/i18n/data/bg.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "изтрит коментар %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Шаблони", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Добави прикачен файл", @@ -190,7 +202,9 @@ "board-view-collapse": "Събери", "board-view-gantt": "План", "board-view-lists": "Списъци", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Отмени", "card-archived": "Тази карта е преместена в Архива.", "board-archived": "Това табло е преместено в Архива.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Създай", "createBoardPopup-title": "Създай Табло", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Импортирай Табло", "createLabelPopup-title": "Създай Табло", "createCustomField": "Създай Поле", @@ -354,6 +369,10 @@ "custom-field-text": "Текст", "custom-fields": "Собствени полета", "date": "Дата", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Отказ", "default-avatar": "Основен аватар", "delete": "Изтрий", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Промени известията", "editProfilePopup-title": "Промяна на профила", "email": "Имейл", + "email-address": "Email Address", "email-enrollAccount-subject": "Ваш профил беше създаден на __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Неуспешно изпращане на имейла", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Всички списъци, карти, имена и действия ще бъдат изтрити и няма да можете да възстановите съдържанието на дъската. Няма връщане назад.", "boardDeletePopup-title": "Изтриване на Таблото?", "delete-board": "Изтрий таблото", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Подзадачи за табло __board__", "default": "по подразбиране", "defaultdefault": "по подразбиране", @@ -755,7 +777,7 @@ "subtask-settings": "Настройки на Подзадачите", "card-settings": "Настройки на Карта", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Настройки за Подзадачите за това Табло", + "boardSubtaskSettingsPopup-title": "Настройки на Подзадачите", "boardCardSettingsPopup-title": "Настройки на Карта", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Вложете под-задачи към тази дъска:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Състояние", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Завършено", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/br.i18n.json b/imports/i18n/data/br.i18n.json index 214e99abc..6cbe2a70b 100644 --- a/imports/i18n/data/br.i18n.json +++ b/imports/i18n/data/br.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Krouiñ", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Diverkañ", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ca.i18n.json b/imports/i18n/data/ca.i18n.json index 9e9ff8d81..349a3e4b0 100644 --- a/imports/i18n/data/ca.i18n.json +++ b/imports/i18n/data/ca.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "Ha esborrar el comentari %s", "activity-receivedDate": "editat la data de recepció a %s de %s", "activity-startDate": "data d'inici editada a %s de %s", + "allboards.starred": "Starred", + "allboards.templates": "Plantilles", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "data de venciment editada a %s de %s", "activity-endDate": "data de finalització editada a %s de %s", "add-attachment": "Afegeix adjunt", @@ -190,7 +202,9 @@ "board-view-collapse": "Contraure", "board-view-gantt": "Gantt", "board-view-lists": "Llistes", - "bucket-example": "Igual que “Bucket List”, per exemple", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel·la", "card-archived": "Aquesta fitxa ha estat moguda al Arxiu.", "board-archived": "Aquest tauler s'ha mogut a l'arxiu", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Títol de la primera fitxa\", \"description\":\"Descripció de la primera fitxa\"}, {\"title\":\"Títol de la segona fitxa\",\"description\":\"Descripció de la segona fitxa \"},{\"title\":\"Títol de l'última fitxa\",\"description\":\"Descripció de l'última fitxa\"} ]", "create": "Crea", "createBoardPopup-title": "Crea tauler", + "createTemplateContainerPopup-title": "Afegeix un Contenidor de plantilles", "chooseBoardSourcePopup-title": "Importa tauler", "createLabelPopup-title": "Crea etiqueta", "createCustomField": "Crear campament", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Camps Personalitzats", "date": "Dades", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Declina", "default-avatar": "Avatar per defecte", "delete": "Esborra", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edita la notificació", "editProfilePopup-title": "Edita el teu Perfil", "email": "Correu electrònic", + "email-address": "Email Address", "email-enrollAccount-subject": "Un compte creat per a tu a __siteName__", "email-enrollAccount-text": "Hola __user__,\n\nPer començar a utilitzar el servei, segueix l'enllaç següent.\n\n__url__\n\nGràcies.", "email-fail": "Error enviant el correu", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Se suprimiran totes les llistes, fitxes, etiquetes i activitats i no podreu recuperar el contingut del tauler. No hi ha cap desfer.", "boardDeletePopup-title": "Vols suprimir el tauler?", "delete-board": "Suprimeix el tauler", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasques per al tauler __board__", "default": "Per defecte", "defaultdefault": "Per defecte", @@ -755,7 +777,7 @@ "subtask-settings": "Configuració de subtasques", "card-settings": "Configuració de fitxa", "minicard-settings": "Configuració de la minifitxa", - "boardSubtaskSettingsPopup-title": "Configuració de les subtasques del tauler", + "boardSubtaskSettingsPopup-title": "Configuració de subtasques", "boardCardSettingsPopup-title": "Configuració de fitxa", "boardMinicardSettingsPopup-title": "Configuració de la minifitxa", "deposit-subtasks-board": "Diposita subtasques a aquest tauler:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "jo", "dueCardsViewChange-choice-all": "Tots els usuaris", "dueCardsViewChange-choice-all-description": "Mostra totes les fitxes incompletes amb una *data de venciment* de taulers per als quals l'usuari té permís.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Fitxes Trencades", "board-title-not-found": "No s'ha trobat el tauler '%s'.", "swimlane-title-not-found": "No s'ha trobat el carril '%s'.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Estat", + "migration-progress-details": "Detalls", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completat", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "de", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ca@valencia.i18n.json b/imports/i18n/data/ca@valencia.i18n.json index 1c069d3c8..e8d3a8b09 100644 --- a/imports/i18n/data/ca@valencia.i18n.json +++ b/imports/i18n/data/ca@valencia.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ca_ES.i18n.json b/imports/i18n/data/ca_ES.i18n.json index f92720a14..5cecaa279 100644 --- a/imports/i18n/data/ca_ES.i18n.json +++ b/imports/i18n/data/ca_ES.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/cmn.i18n.json b/imports/i18n/data/cmn.i18n.json index 75877ecfe..45bc58d1b 100644 --- a/imports/i18n/data/cmn.i18n.json +++ b/imports/i18n/data/cmn.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/cs-CZ.i18n.json b/imports/i18n/data/cs-CZ.i18n.json index 4ec7f07b8..e330e3f2a 100644 --- a/imports/i18n/data/cs-CZ.i18n.json +++ b/imports/i18n/data/cs-CZ.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "smazat komentář %s", "activity-receivedDate": "editoval(a) datum přijetí na %s z %s", "activity-startDate": "editoval(a) datum zahájení na %s z %s", + "allboards.starred": "Starred", + "allboards.templates": "Šablony", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "editoval(a) termín dokončení na %s z %s", "activity-endDate": "editoval(a) datum ukončení na %s z %s", "add-attachment": "Přidat přílohu", @@ -190,7 +202,9 @@ "board-view-collapse": "Sbalit", "board-view-gantt": "Gannt", "board-view-lists": "Sloupce", - "bucket-example": "Například \"O čem sním\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Zrušit", "card-archived": "Karta byla přesunuta do archivu.", "board-archived": "Toto tablo je přesunuto do archivu.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Nadpis první karty\", \"description\":\"Popis první karty\"}, {\"title\":\"Nadpis druhé karty\",\"description\":\"Popis druhé karty\"},{\"title\":\"Nadpis poslední kary\",\"description\":\"Popis poslední karty\"} ]", "create": "Vytvořit", "createBoardPopup-title": "Vytvořit tablo", + "createTemplateContainerPopup-title": "Přidat kontejner šablony", "chooseBoardSourcePopup-title": "Importovat tablo", "createLabelPopup-title": "Vytvořit štítek", "createCustomField": "Vytvořit pole", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Vlastní pole", "date": "Datum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Zamítnout", "default-avatar": "Výchozí avatar", "delete": "Smazat", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Změnit notifikace", "editProfilePopup-title": "Upravit profil", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Byl vytvořen účet na __siteName__", "email-enrollAccount-text": "Ahoj __user__,\n\nMůžeš začít používat službu kliknutím na odkaz níže.\n\n__url__\n\nDěkujeme.", "email-fail": "Odeslání emailu selhalo", @@ -748,6 +768,8 @@ "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?", "delete-board": "Smazat tablo", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Podúkoly pro tablo __board__", "default": "Výchozí", "defaultdefault": "Výchozí", @@ -755,7 +777,7 @@ "subtask-settings": "Nastavení podúkolů", "card-settings": "Nastavení karet", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Nastavení podúkolů tabla", + "boardSubtaskSettingsPopup-title": "Nastavení podúkolů", "boardCardSettingsPopup-title": "Nastavení karet", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Vložit podúkoly do tohoto tabla", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Moje", "dueCardsViewChange-choice-all": "Všechny", "dueCardsViewChange-choice-all-description": "Zobrazí všechny nedokončené karty s *Termínem dokončení* z každého tabla, ke kterému má uživatel oprávnění.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Rozbité karty", "board-title-not-found": "Tablo '%s' nenalezeno.", "swimlane-title-not-found": "Swimlane '%s' nenalezena.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Stav", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Dokončeno", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "z", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/cs.i18n.json b/imports/i18n/data/cs.i18n.json index 8161b653f..84cc45b7e 100644 --- a/imports/i18n/data/cs.i18n.json +++ b/imports/i18n/data/cs.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "smazat komentář %s", "activity-receivedDate": "editoval(a) datum přijetí na %s z %s", "activity-startDate": "editoval(a) datum zahájení na %s z %s", + "allboards.starred": "Starred", + "allboards.templates": "Šablony", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "editoval(a) termín dokončení na %s z %s", "activity-endDate": "editoval(a) datum ukončení na %s z %s", "add-attachment": "Přidat přílohu", @@ -190,7 +202,9 @@ "board-view-collapse": "Sbalit", "board-view-gantt": "Gannt", "board-view-lists": "Sloupce", - "bucket-example": "Například \"O čem sním\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Zrušit", "card-archived": "Karta byla přesunuta do archivu.", "board-archived": "Toto tablo je přesunuto do archivu.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Nadpis první karty\", \"description\":\"Popis první karty\"}, {\"title\":\"Nadpis druhé karty\",\"description\":\"Popis druhé karty\"},{\"title\":\"Nadpis poslední kary\",\"description\":\"Popis poslední karty\"} ]", "create": "Vytvořit", "createBoardPopup-title": "Vytvořit tablo", + "createTemplateContainerPopup-title": "Přidat kontejner šablony", "chooseBoardSourcePopup-title": "Importovat tablo", "createLabelPopup-title": "Vytvořit štítek", "createCustomField": "Vytvořit pole", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Vlastní pole", "date": "Datum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Zamítnout", "default-avatar": "Výchozí avatar", "delete": "Smazat", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Změnit notifikace", "editProfilePopup-title": "Upravit profil", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Byl vytvořen účet na __siteName__", "email-enrollAccount-text": "Ahoj __user__,\n\nMůžeš začít používat službu kliknutím na odkaz níže.\n\n__url__\n\nDěkujeme.", "email-fail": "Odeslání emailu selhalo", @@ -748,6 +768,8 @@ "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?", "delete-board": "Smazat tablo", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Podúkoly pro tablo __board__", "default": "Výchozí", "defaultdefault": "Výchozí", @@ -755,7 +777,7 @@ "subtask-settings": "Nastavení podúkolů", "card-settings": "Nastavení karet", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Nastavení podúkolů tabla", + "boardSubtaskSettingsPopup-title": "Nastavení podúkolů", "boardCardSettingsPopup-title": "Nastavení karet", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Vložit podúkoly do tohoto tabla", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Moje", "dueCardsViewChange-choice-all": "Všechny", "dueCardsViewChange-choice-all-description": "Zobrazí všechny nedokončené karty s *Termínem dokončení* z každého tabla, ke kterému má uživatel oprávnění.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Rozbité karty", "board-title-not-found": "Tablo '%s' nenalezeno.", "swimlane-title-not-found": "Swimlane '%s' nenalezena.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Stav", + "migration-progress-details": "Podrobnosti", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Dokončeno", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "z", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/cy-GB.i18n.json b/imports/i18n/data/cy-GB.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/cy-GB.i18n.json +++ b/imports/i18n/data/cy-GB.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/cy.i18n.json b/imports/i18n/data/cy.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/cy.i18n.json +++ b/imports/i18n/data/cy.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/da.i18n.json b/imports/i18n/data/da.i18n.json index 9d25199a5..4edbf48bc 100644 --- a/imports/i18n/data/da.i18n.json +++ b/imports/i18n/data/da.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "slettede kommentar %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Skabeloner", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Tilføj vedhæftning", @@ -190,7 +202,9 @@ "board-view-collapse": "Sammenfold", "board-view-gantt": "Gantt", "board-view-lists": "Lister", - "bucket-example": "Eksempelvis \"Bucked-liste\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Annullér", "card-archived": "Dette kort blev flyttet til arkivet.", "board-archived": "Denne tavle blev flyttet til arkivet.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Opret", "createBoardPopup-title": "Opret tavle", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importér tavle", "createLabelPopup-title": "Opret etikette", "createCustomField": "Opret felt", @@ -354,6 +369,10 @@ "custom-field-text": "Tekst", "custom-fields": "Brugerdefinerede felter", "date": "Dato", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Afslå", "default-avatar": "Standard-avatar", "delete": "Slet", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Redigér notifikation", "editProfilePopup-title": "Redigér profil", "email": "E-mail", + "email-address": "Email Address", "email-enrollAccount-subject": "Der er oprettet konto til dig på __siteName__", "email-enrollAccount-text": "Hej __user__,\n\nFor at begynde at benytte tjenesten, så klik linket nedenfor.\n\n__url__\n\nTak.", "email-fail": "Afsendelse af e-mail mislykkedes", @@ -748,6 +768,8 @@ "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?", "delete-board": "Slet tavle", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Delopgaver for tavlen __board__", "default": "Standard", "defaultdefault": "Standard", @@ -755,7 +777,7 @@ "subtask-settings": "Indstillinger for delopgaver", "card-settings": "Indstillinger for kort", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Indstillinger for delopgaver i tavle", + "boardSubtaskSettingsPopup-title": "Indstillinger for delopgaver", "boardCardSettingsPopup-title": "Indstillinger for kort", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Indsæt delopgaver på denne tavle:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Fuldført", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "af", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/de-AT.i18n.json b/imports/i18n/data/de-AT.i18n.json index 55e7daa3f..eeac5f73b 100644 --- a/imports/i18n/data/de-AT.i18n.json +++ b/imports/i18n/data/de-AT.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "löschte Kommentar %s", "activity-receivedDate": "hat Empfangsdatum zu %s geändert auf %s", "activity-startDate": "hat Startdatum zu %s geändert auf %s", + "allboards.starred": "Starred", + "allboards.templates": "Vorlagen", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "hat Fälligkeitsdatum zu %s geändert auf %s", "activity-endDate": "hat Enddatum zu %s geändert auf %s", "add-attachment": "Datei anhängen", @@ -190,7 +202,9 @@ "board-view-collapse": "Einklappen", "board-view-gantt": "Gantt", "board-view-lists": "Listen", - "bucket-example": "z.B. \"Löffelliste\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Abbrechen", "card-archived": "Diese Karte wurde ins Archiv verschoben", "board-archived": "Dieses Board wurde ins Archiv verschoben.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Titel der ersten Karte\", \"description\":\"Beschreibung der ersten Karte\"}, {\"title\":\"Titel der zweiten Karte\",\"description\":\"Beschreibung der zweiten Karte\"},{\"title\":\"Titel der letzten Karte\",\"description\":\"Beschreibung der letzten Karte\"} ]", "create": "Erstellen", "createBoardPopup-title": "Board erstellen", + "createTemplateContainerPopup-title": "Vorlagen-Container hinzufügen", "chooseBoardSourcePopup-title": "Board importieren", "createLabelPopup-title": "Label erstellen", "createCustomField": "Feld erstellen", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Benutzerdefinierte Felder", "date": "Datum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Ablehnen", "default-avatar": "Standard Profilbild", "delete": "Löschen", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Benachrichtigung ändern", "editProfilePopup-title": "Profil ändern", "email": "E-Mail", + "email-address": "Email Address", "email-enrollAccount-subject": "Ihr Benutzerkonto auf __siteName__ wurde erstellt", "email-enrollAccount-text": "Hallo __user__,\n\num den Dienst nutzen zu können, klicken Sie bitte auf folgenden Link:\n\n__url__\n\nDanke.", "email-fail": "Senden der E-Mail fehlgeschlagen", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Alle Listen, Karten, Labels und Akivitäten werden gelöscht und Sie können die Inhalte des Boards nicht wiederherstellen! Die Aktion kann nicht rückgängig gemacht werden.", "boardDeletePopup-title": "Board löschen?", "delete-board": "Board löschen", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Teilaufgabe für __board__ Board", "default": "Standard", "defaultdefault": "Standard", @@ -755,7 +777,7 @@ "subtask-settings": "Einstellungen für Teilaufgaben", "card-settings": "Karten-Einstellungen", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Boardeinstellungen für Teilaufgaben", + "boardSubtaskSettingsPopup-title": "Einstellungen für Teilaufgaben", "boardCardSettingsPopup-title": "Karten-Einstellungen", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Teilaufgaben in diesem Board ablegen:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Ich", "dueCardsViewChange-choice-all": "alle Benutzer", "dueCardsViewChange-choice-all-description": "Zeigt alle unvollständigen Karten mit einem *Fälligkeits*-Datum auf Boards, für die der Benutzer Berechtigungen hat.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Fehlerhafte Karten", "board-title-not-found": "Board „%s“ nicht gefunden.", "swimlane-title-not-found": "Swimlane „%s“ nicht gefunden.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "abgeschlossen", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "von", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/de-CH.i18n.json b/imports/i18n/data/de-CH.i18n.json index 93e1dbb83..afdea98f1 100644 --- a/imports/i18n/data/de-CH.i18n.json +++ b/imports/i18n/data/de-CH.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "löschte Kommentar %s", "activity-receivedDate": "hat Empfangsdatum zu %s geändert auf %s", "activity-startDate": "hat Startdatum zu %s geändert auf %s", + "allboards.starred": "Starred", + "allboards.templates": "Vorlagen", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "hat Fälligkeitsdatum zu %s geändert auf %s", "activity-endDate": "hat Enddatum zu %s geändert auf %s", "add-attachment": "Datei anhängen", @@ -190,7 +202,9 @@ "board-view-collapse": "Einklappen", "board-view-gantt": "Gantt", "board-view-lists": "Listen", - "bucket-example": "z.B. \"Löffelliste\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Abbrechen", "card-archived": "Diese Karte wurde ins Archiv verschoben", "board-archived": "Dieses Board wurde ins Archiv verschoben.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Titel der ersten Karte\", \"description\":\"Beschreibung der ersten Karte\"}, {\"title\":\"Titel der zweiten Karte\",\"description\":\"Beschreibung der zweiten Karte\"},{\"title\":\"Titel der letzten Karte\",\"description\":\"Beschreibung der letzten Karte\"} ]", "create": "Erstellen", "createBoardPopup-title": "Board erstellen", + "createTemplateContainerPopup-title": "Vorlagen-Container hinzufügen", "chooseBoardSourcePopup-title": "Board importieren", "createLabelPopup-title": "Label erstellen", "createCustomField": "Feld erstellen", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Benutzerdefinierte Felder", "date": "Datum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Ablehnen", "default-avatar": "Standard Profilbild", "delete": "Löschen", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Benachrichtigung ändern", "editProfilePopup-title": "Profil ändern", "email": "E-Mail", + "email-address": "Email Address", "email-enrollAccount-subject": "Ihr Benutzerkonto auf __siteName__ wurde erstellt", "email-enrollAccount-text": "Hallo __user__,\n\num den Dienst nutzen zu können, klicken Sie bitte auf folgenden Link:\n\n__url__\n\nDanke.", "email-fail": "Senden der E-Mail fehlgeschlagen", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Alle Listen, Karten, Labels und Akivitäten werden gelöscht und Sie können die Inhalte des Boards nicht wiederherstellen! Die Aktion kann nicht rückgängig gemacht werden.", "boardDeletePopup-title": "Board löschen?", "delete-board": "Board löschen", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Teilaufgabe für __board__ Board", "default": "Standard", "defaultdefault": "Standard", @@ -755,7 +777,7 @@ "subtask-settings": "Einstellungen für Teilaufgaben", "card-settings": "Karten-Einstellungen", "minicard-settings": "Einstellungen für Minikarte", - "boardSubtaskSettingsPopup-title": "Boardeinstellungen für Teilaufgaben", + "boardSubtaskSettingsPopup-title": "Einstellungen für Teilaufgaben", "boardCardSettingsPopup-title": "Karten-Einstellungen", "boardMinicardSettingsPopup-title": "Einstellungen für Minikarte", "deposit-subtasks-board": "Teilaufgaben in diesem Board ablegen:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Ich", "dueCardsViewChange-choice-all": "alle Benutzer", "dueCardsViewChange-choice-all-description": "Zeigt alle unvollständigen Karten mit einem *Fälligkeits*-Datum auf Boards, für die der Benutzer Berechtigungen hat.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Fehlerhafte Karten", "board-title-not-found": "Board „%s“ nicht gefunden.", "swimlane-title-not-found": "Swimlane „%s“ nicht gefunden.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "abgeschlossen", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "von", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/de.i18n.json b/imports/i18n/data/de.i18n.json index 72c23bd58..cfb4ea635 100644 --- a/imports/i18n/data/de.i18n.json +++ b/imports/i18n/data/de.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "löschte Kommentar %s", "activity-receivedDate": "hat Empfangsdatum zu %s geändert auf %s", "activity-startDate": "hat Startdatum zu %s geändert auf %s", + "allboards.starred": "Starred", + "allboards.templates": "Vorlagen", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "hat Fälligkeitsdatum zu %s geändert auf %s", "activity-endDate": "hat Enddatum zu %s geändert auf %s", "add-attachment": "Datei anhängen", @@ -190,7 +202,9 @@ "board-view-collapse": "Einklappen", "board-view-gantt": "Gantt", "board-view-lists": "Listen", - "bucket-example": "z.B. \"Löffelliste\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Abbrechen", "card-archived": "Diese Karte wurde ins Archiv verschoben", "board-archived": "Dieses Board wurde ins Archiv verschoben.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Titel der ersten Karte\", \"description\":\"Beschreibung der ersten Karte\"}, {\"title\":\"Titel der zweiten Karte\",\"description\":\"Beschreibung der zweiten Karte\"},{\"title\":\"Titel der letzten Karte\",\"description\":\"Beschreibung der letzten Karte\"} ]", "create": "Erstellen", "createBoardPopup-title": "Board erstellen", + "createTemplateContainerPopup-title": "Vorlagen-Container hinzufügen", "chooseBoardSourcePopup-title": "Board importieren", "createLabelPopup-title": "Label erstellen", "createCustomField": "Feld erstellen", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Benutzerdefinierte Felder", "date": "Datum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Ablehnen", "default-avatar": "Standard Profilbild", "delete": "Löschen", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Benachrichtigung ändern", "editProfilePopup-title": "Profil ändern", "email": "E-Mail", + "email-address": "Email Address", "email-enrollAccount-subject": "Ihr Benutzerkonto auf __siteName__ wurde erstellt", "email-enrollAccount-text": "Hallo __user__,\n\num den Dienst nutzen zu können, klicken Sie bitte auf folgenden Link:\n\n__url__\n\nDanke.", "email-fail": "Senden der E-Mail fehlgeschlagen", @@ -631,9 +651,9 @@ "upload": "Upload", "upload-avatar": "Profilbild hochladen", "uploaded-avatar": "Profilbild hochgeladen", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "Dateien hochladen", + "upload-failed": "Hochladen fehlgeschlagen", + "upload-completed": "Hochladen ist abgeschlossen", "custom-top-left-corner-logo-image-url": "Benutzerdefiniertes Logo oben links Bild URL", "custom-top-left-corner-logo-link-url": "Benutzerdefiniertes Logo oben links Link URL", "custom-top-left-corner-logo-height": "Benutzerdefiniertes Logo oben links Höhe. Voreinstellung: 27", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Alle Listen, Karten, Labels und Akivitäten werden gelöscht und Sie können die Inhalte des Boards nicht wiederherstellen! Die Aktion kann nicht rückgängig gemacht werden.", "boardDeletePopup-title": "Board löschen?", "delete-board": "Board löschen", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Teilaufgabe für __board__ Board", "default": "Standard", "defaultdefault": "Standard", @@ -755,7 +777,7 @@ "subtask-settings": "Einstellungen für Teilaufgaben", "card-settings": "Karten-Einstellungen", "minicard-settings": "Minikarte-Einstellungen", - "boardSubtaskSettingsPopup-title": "Boardeinstellungen für Teilaufgaben", + "boardSubtaskSettingsPopup-title": "Einstellungen für Teilaufgaben", "boardCardSettingsPopup-title": "Karten-Einstellungen", "boardMinicardSettingsPopup-title": "Minikarte-Einstellungen", "deposit-subtasks-board": "Teilaufgaben in diesem Board ablegen:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Ich", "dueCardsViewChange-choice-all": "alle Benutzer", "dueCardsViewChange-choice-all-description": "Zeigt alle unvollständigen Karten mit einem *Fälligkeits*-Datum auf Boards, für die der Benutzer Berechtigungen hat.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Fehlerhafte Karten", "board-title-not-found": "Board „%s“ nicht gefunden.", "swimlane-title-not-found": "Swimlane „%s“ nicht gefunden.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "Benutzer ist Aktiv - zum Deaktivieren klicken", "admin-people-user-inactive": "Benutzer ist Inaktiv - zum Aktivieren klicken", "accounts-lockout-all-users-unlocked": "Alle gesperrten Benutzer wurden entsperrt", - "accounts-lockout-unlock-all": "Alle entsperren" + "accounts-lockout-unlock-all": "Alle entsperren", + "active-cron-jobs": "Aktive geplante Aufgaben", + "add-cron-job": "Geplante Aufgabe hinzufügen", + "add-cron-job-placeholder": "Funktion „Geplante Aufgaben hinzufügen” in Kürze verfügbar", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Abgeschlossen", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "abgeschlossen", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "von", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Gewicht", + "idle": "Leerlauf", + "complete": "Abgeschlossen", + "cron": "Zeitplan" } diff --git a/imports/i18n/data/de_DE.i18n.json b/imports/i18n/data/de_DE.i18n.json index 90b501921..792d13633 100644 --- a/imports/i18n/data/de_DE.i18n.json +++ b/imports/i18n/data/de_DE.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "löschte Kommentar %s", "activity-receivedDate": "hat Empfangsdatum zu %s geändert auf %s", "activity-startDate": "hat Startdatum zu %s geändert auf %s", + "allboards.starred": "Starred", + "allboards.templates": "Vorlagen", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "hat Fälligkeitsdatum zu %s geändert auf %s", "activity-endDate": "hat Enddatum zu %s geändert auf %s", "add-attachment": "Datei anhängen", @@ -177,20 +189,22 @@ "boardChangeViewPopup-title": "Boardansicht", "boards": "Boards", "board-view": "Boardansicht", - "desktop-mode": "Desktop Mode", - "mobile-mode": "Mobile Mode", - "mobile-desktop-toggle": "Toggle between Mobile and Desktop Mode", + "desktop-mode": "Desktop-Modus", + "mobile-mode": "Handy-Modus", + "mobile-desktop-toggle": "Umschalten zwischen Mobil und Desktop Ansicht", "zoom-in": "Vergrößern", "zoom-out": "Verkleinern", - "click-to-change-zoom": "Click to change zoom level", - "zoom-level": "Zoom Level", - "enter-zoom-level": "Enter zoom level (50-300%):", + "click-to-change-zoom": "Klicken um die Zoom Stufe zu ändern", + "zoom-level": "Zoomstufe", + "enter-zoom-level": "Eingabe Zoom Stufe (50-300%):", "board-view-cal": "Kalender", "board-view-swimlanes": "Swimlanes", "board-view-collapse": "Einklappen", "board-view-gantt": "Gantt", "board-view-lists": "Listen", "bucket-example": "z.B. \"Löffelliste\"", + "calendar-previous-month-label": "Vorheriger Monat", + "calendar-next-month-label": "Nächster Monat", "cancel": "Abbrechen", "card-archived": "Diese Karte wurde ins Archiv verschoben", "board-archived": "Dieses Board wurde ins Archiv verschoben.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Titel der ersten Karte\", \"description\":\"Beschreibung der ersten Karte\"}, {\"title\":\"Titel der zweiten Karte\",\"description\":\"Beschreibung der zweiten Karte\"},{\"title\":\"Titel der letzten Karte\",\"description\":\"Beschreibung der letzten Karte\"} ]", "create": "Erstellen", "createBoardPopup-title": "Board erstellen", + "createTemplateContainerPopup-title": "Vorlagen-Container hinzufügen", "chooseBoardSourcePopup-title": "Board importieren", "createLabelPopup-title": "Label erstellen", "createCustomField": "Feld erstellen", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Benutzerdefinierte Felder", "date": "Datum", + "date-format": "Datumsformat", + "date-format-yyyy-mm-dd": "JJJJ-MM-TT hh:mm", + "date-format-dd-mm-yyyy": "TT-MM-JJJJ", + "date-format-mm-dd-yyyy": "MM-TT-JJJJ", "decline": "Ablehnen", "default-avatar": "Standard Profilbild", "delete": "Löschen", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Benachrichtigung ändern", "editProfilePopup-title": "Profil ändern", "email": "E-Mail", + "email-address": "E-Mail Adresse", "email-enrollAccount-subject": "Ihr Benutzerkonto auf __siteName__ wurde erstellt", "email-enrollAccount-text": "Hallo __user__,\n\num den Dienst nutzen zu können, klicken Sie bitte auf folgenden Link:\n\n__url__\n\nDanke.", "email-fail": "Senden der E-Mail fehlgeschlagen", @@ -631,9 +651,9 @@ "upload": "Upload", "upload-avatar": "Profilbild hochladen", "uploaded-avatar": "Profilbild hochgeladen", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "Dateien hochladen", + "upload-failed": "Hochladen fehlgeschlagen", + "upload-completed": "Hochladen ist abgeschlossen", "custom-top-left-corner-logo-image-url": "Benutzerdefiniertes Logo oben links Bild URL", "custom-top-left-corner-logo-link-url": "Benutzerdefiniertes Logo oben links Link URL", "custom-top-left-corner-logo-height": "Benutzerdefiniertes Logo oben links Höhe. Voreinstellung: 27", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Alle Listen, Karten, Labels und Akivitäten werden gelöscht und Sie können die Inhalte des Boards nicht wiederherstellen! Die Aktion kann nicht rückgängig gemacht werden.", "boardDeletePopup-title": "Board löschen?", "delete-board": "Board löschen", + "delete-duplicate-lists": "Lösche doppelte Listen", + "delete-duplicate-lists-confirm": "Sicher? Es werden alle doppelten Listen gelöscht, die den gleichen Namen haben und keine Karten enthalten.", "default-subtasks-board": "Teilaufgabe für __board__ Board", "default": "Standard", "defaultdefault": "Standard", @@ -755,7 +777,7 @@ "subtask-settings": "Einstellungen für Teilaufgaben", "card-settings": "Karten-Einstellungen", "minicard-settings": "Minikarte-Einstellungen", - "boardSubtaskSettingsPopup-title": "Boardeinstellungen für Teilaufgaben", + "boardSubtaskSettingsPopup-title": "Einstellungen für Teilaufgaben", "boardCardSettingsPopup-title": "Karten-Einstellungen", "boardMinicardSettingsPopup-title": "Minikarte-Einstellungen", "deposit-subtasks-board": "Teilaufgaben in diesem Board ablegen:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Ich", "dueCardsViewChange-choice-all": "alle Benutzer", "dueCardsViewChange-choice-all-description": "Zeigt alle unvollständigen Karten mit einem *Fälligkeits*-Datum auf Boards, für die der Benutzer Berechtigungen hat.", + "dueCards-noResults-title": "Keine fälligen Karten gefunden", + "dueCards-noResults-description": "Sie haben momentan keine Karten mit Fälligkeitsdaten.", "broken-cards": "Fehlerhafte Karten", "board-title-not-found": "Board „%s“ nicht gefunden.", "swimlane-title-not-found": "Swimlane „%s“ nicht gefunden.", @@ -1284,14 +1308,14 @@ "accessibility-info-not-added-yet": "Es wurde noch keine Information zur Bedienungshilfe hinzugefügt", "accessibility-title": "Bedienungshilfe Titel", "accessibility-content": "Barrierefreier Eintrag", - "accounts-lockout-settings": "Brute Force Protection Settings", - "accounts-lockout-info": "These settings control how login attempts are protected against brute force attacks.", - "accounts-lockout-known-users": "Settings for known users (correct username, wrong password)", - "accounts-lockout-unknown-users": "Settings for unknown users (non-existent username)", + "accounts-lockout-settings": "Brute-Force-Schutz Einstellungen", + "accounts-lockout-info": "Diese Einstellungen steuern, wie Anmeldeversuche gegen Brute-Force-Angriffe geschützt werden", + "accounts-lockout-known-users": "Einstellungen für bekannte Benutzer (korrekter Benutzername, falsches Passwort)", + "accounts-lockout-unknown-users": "Einstellungen für unbekannte Benutzer (nicht existierender Benutzername)", "accounts-lockout-failures-before": "Fehler vor einer Sperrung", "accounts-lockout-period": "Dauer der Sperrung (Sekunden)", - "accounts-lockout-failure-window": "Failure window (seconds)", - "accounts-lockout-settings-updated": "Brute force protection settings have been updated", + "accounts-lockout-failure-window": "Fehlerfenster (Sekunden)", + "accounts-lockout-settings-updated": "Die Brute-force-Schutz Einstellungen wurden aktualisiert", "accounts-lockout-locked-users": "Gesperrte Benutzer", "accounts-lockout-locked-users-info": "Kürzlich gesperrte Benutzer aufgrund von zu vielen fehlerhaften Logins", "accounts-lockout-no-locked-users": "Es gibt aktuell keine gesperrten Benutzer", @@ -1299,19 +1323,257 @@ "accounts-lockout-remaining-time": "Verbleibende Zeit", "accounts-lockout-user-unlocked": "Benutzer wurde erfolgreich entsperrt", "accounts-lockout-confirm-unlock": "Wollen Sie den Benutzer wirklich entsperren?", - "accounts-lockout-confirm-unlock-all": "Are you sure you want to unlock all locked users?", - "accounts-lockout-show-locked-users": "Show locked users only", + "accounts-lockout-confirm-unlock-all": "Wollen Sie wirklich alle gesperrten Benutzer entsperren?", + "accounts-lockout-show-locked-users": "Zeige nur gesperrte Benutzer", "accounts-lockout-user-locked": "Benutzer ist gesperrt", "accounts-lockout-click-to-unlock": "Klicken Sie, um den Benutzer zu entsperren", "accounts-lockout-status": "Status", - "admin-people-filter-show": "Show:", + "admin-people-filter-show": "Zeige:", "admin-people-filter-all": "alle Benutzer", - "admin-people-filter-locked": "Locked Users Only", + "admin-people-filter-locked": "Nur gesperrte Benutzer", "admin-people-filter-active": "Aktiv", - "admin-people-filter-inactive": "Not Active", + "admin-people-filter-inactive": "Nicht aktiv", "admin-people-active-status": "Aktiv Status", - "admin-people-user-active": "User is active - click to deactivate", - "admin-people-user-inactive": "User is inactive - click to activate", - "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "admin-people-user-active": "Benutzer ist aktiv - zum Deaktivieren klicken", + "admin-people-user-inactive": "Benutzer ist inaktiv - zum Aktivieren klicken", + "accounts-lockout-all-users-unlocked": "Alle gesperrten Benutzer wurden entsperrt", + "accounts-lockout-unlock-all": "Alle entsperren", + "active-cron-jobs": "Aktive geplante Aufgaben", + "add-cron-job": "Geplante Aufgabe hinzufügen", + "add-cron-job-placeholder": "Funktion „Geplante Aufgaben hinzufügen” in Kürze verfügbar", + "attachment-storage-configuration": "Konfiguration des Anhangspeichers", + "attachments-path": "Anhänge Pfad", + "attachments-path-description": "Pfad unter dem die Anhänge gespeichert werden", + "avatars-path": "Pfad zu den Avataren", + "avatars-path-description": "Pfad unter dem die Avatardateien gespeichert werden", + "board-archive-failed": "Planung der Brettarchivierung fehlgeschlagen ", + "board-archive-scheduled": "Brettarchivierung erfolgreich eingeplant", + "board-backup-failed": "Planung der Brettsicherung fehlgeschlagen ", + "board-backup-scheduled": "Brettsicherung erfolgreich eingeplant", + "board-cleanup-failed": "Planung des Brettaufräumens fehlgeschlagen", + "board-cleanup-scheduled": "Brettaufräumen erfolgreich eingeplant", + "board-operations": "Brettoperationen", + "cron-jobs": "Geplante Aufgaben", + "cron-migrations": "Geplante Migrationen", + "cron-job-delete-confirm": "Sind Sie sicher, dass Sie diese geplante Aufgabe löschen wollen?", + "cron-job-delete-failed": "Löschen der geplanten Aufgabe fehlgeschlagen", + "cron-job-deleted": "Geplante Aufgabe erfolgreich gelöscht", + "cron-job-pause-failed": "Anhalten der geplanten Aufgabe fehlgeschlagen", + "cron-job-paused": "Geplante Aufgabe erfolgreich angehalten", + "filesystem-path-description": "Basispfad des Dateispeichers", + "gridfs-enabled": "GridFS aktiviert", + "gridfs-enabled-description": "Benutze MongoDB GridFS als Dateispeicher", + "migration-pause-failed": "Unterbrechung der Migrationen fehlgeschlagen", + "migration-paused": "Migrationen erfolgreich unterbrochen", + "migration-progress": "Migrationsfortschritt", + "migration-start-failed": "Start der Migrationen fehlgeschlagen", + "migration-started": "Migrationen erfolgreich gestartet", + "migration-status": "Migrationsstatus", + "migration-stop-confirm": "Sind Sie sicher, dass Sie alle Migrationen stoppen wollen?", + "migration-stop-failed": "Stoppen der Migrationen fehlgeschlagen", + "migration-stopped": "Migrationen erfolgreich gestoppt", + "mongodb-gridfs-storage": "MongoDB GridFS Speicher", + "pause-all-migrations": "Alle Migrationen anhalten", + "s3-access-key": "S3 Zugriffsschlüssel", + "s3-access-key-description": "AWS S3 Zugangsschlüssel zur Authentifizierung", + "s3-access-key-placeholder": "S3 Zugriffsschlüssel eingeben", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 Bucket Name um Dateien zu speichern", + "s3-connection-failed": "S3 Verbindung fehlgeschlagen", + "s3-connection-success": "S3 Verbindung erfolgreich", + "s3-enabled": "S3 aktiviert", + "s3-enabled-description": "Benutze AWS S3 oder MiniIO als Dateispeicher", + "s3-endpoint": "S3 Endpunkt", + "s3-endpoint-description": "S3 Endpunkt URL (z.B., s3.amazonaws.com oder minio.example.com)", + "s3-minio-storage": "S3/MinIO Speicher", + "s3-port": "S3 Port", + "s3-port-description": "S3 Endpunkt Port Nummer", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 Region (z.B., us-east-1)", + "s3-secret-key": "S3 geheimer Schlüssel", + "s3-secret-key-description": "AWS S3 geheimer Schlüssel zur Authentifizierung", + "s3-secret-key-placeholder": "S3 geheimen Schlüssel eingeben", + "s3-secret-key-required": "S3 geheimer Schlüssel ist erforderlich", + "s3-settings-save-failed": "Speicherung der S3 Einstellungen fehlgeschlagen", + "s3-settings-saved": "S3 Einstellungen erfolgreich gespeichert", + "s3-ssl-enabled": "S3 SSL aktiviert", + "s3-ssl-enabled-description": "Benutze SSL/TLS für S3 Verbindungen", + "save-s3-settings": "S3 Einstellungen speichern", + "schedule-board-archive": "Planung Brettarchiv", + "schedule-board-backup": "Planung Brettsicherung", + "schedule-board-cleanup": "Planung Brettsäuberung", + "scheduled-board-operations": "Geplante Brettoperationen", + "start-all-migrations": "Starte alle Migrationen", + "stop-all-migrations": "Stoppe alle Migrationen", + "test-s3-connection": "Teste S3 Verbindungen", + "writable-path": "Beschreibbarer Pfad", + "writable-path-description": "Basispfad des Dateispeichers", + "add-job": "Aufgabe hinzufügen", + "attachment-migration": "Anhangmigration", + "attachment-monitoring": "Anhangüberwachung", + "attachment-settings": "Anhangeinstellungen", + "attachment-storage-settings": "Speichereinstellungen", + "automatic-migration": "Automatische Migration", + "back-to-settings": "Zurück zu den Einstellungen", + "board-id": "Brett ID", + "board-migration": "Brettmigration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Zeige Listen auf der Minikarte", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Vollständig", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Gesamtfortschritt", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Aufräumen", + "cleanup-old-jobs": "Alte Aufgaben aufräumen", + "completed": "abgeschlossen", + "conversion-info-text": "Diese Umstellung wird einmal pro Brett durchgeführt und verbessert die Performanz. Sie können das Brett normal verwenden.", + "converting-board": "Brett umwandeln", + "converting-board-description": "Umwandlung der Brettstruktur für verbesserte Funktionalität. Das kann einen Moment dauern.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Laufender Vorgang", + "database-migration": "Datenbankmigration", + "database-migration-description": "Update der Datenbankstruktur für eine Verbesserung der Funktionalität und der Performanz. Das kann ein paar Minuten dauern.", + "database-migrations": "Datenbankmigration", + "days-old": "Tage alt", + "duration": "Dauer", + "errors": "Fehler", + "estimated-time-remaining": "Geschätzte Zeit übrig", + "every-1-day": "Jeden Tag", + "every-1-hour": "Jede Stunde", + "every-1-minute": "Jede Minute", + "every-10-minutes": "Alle 10 Minuten", + "every-30-minutes": "Alle 30 Minuten", + "every-5-minutes": "Alle 5 Minuten", + "every-6-hours": "Alle 6 Stunden", + "export-monitoring": "Exportüberwachung", + "filesystem-attachments": "Dateisystemanhänge", + "filesystem-size": "Dateisystem Größe", + "filesystem-storage": "Dateisystem Speicher", + "force-board-scan": "Erzwinge Brettscan", + "gridfs-attachments": "GridFS Anhänge", + "gridfs-size": "GridFS Größe", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Verberge Liste auf der Minikarte", + "idle-migration": "Untätige Migration", + "job-description": "Aufgabenbeschreibung", + "job-details": "Aufgabendetails", + "job-name": "Aufgabenname", + "job-queue": "Aufgabenwarteschlange", + "last-run": "Letzte Ausführung", + "max-concurrent": "Max. gleichzeitig", + "memory-usage": "Speicherauslastung", + "migrate-all-to-filesystem": "Migriere alles ins Dateisystem", + "migrate-all-to-gridfs": "Migriere alles ins GridFS", + "migrate-all-to-s3": "Migriere alles ins S3", + "migrated-attachments": "Migrierte Anhänge", + "migration-batch-size": "Batchgröße", + "migration-batch-size-description": "Anzahl der zu bearbeitenden Anhänge pro Batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Unterbreche Migration, wenn CPU Benutzung diesen Wert überschreitet (10-90%)", + "migration-delay-ms": "Verzögerung (ms)", + "migration-delay-ms-description": "Verzögerung zwischen Batches in Millisekunden (100-10000)", + "migration-detector": "Migrationdetektor", + "migration-info-text": "Datenbankmigrationen werden einmal durchgeführt und verbessern die Systemperformanz. Dieser Vorgang läuft im Hintergrund weiter, auch wenn Sie den Browser schließen.", + "migration-log": "Migration Log", + "migration-markers": "Migrationsmarkierungen", + "migration-resume-failed": "Fortfahren der Migration misslungen", + "migration-resumed": "Migration fortgesetzt", + "migration-steps": "Migrationsschritte", + "migration-warning-text": "Bitte schließen Sie nicht den Browser während der Migration. Der Vorgang wird zwar im Hintergrund fortgesetzt, braucht aber länger.", + "monitoring-export-failed": "Export der Beobachtungsdaten misslungen", + "monitoring-refresh-failed": "Neuladen der Beobachtungsdaten misslungen", + "next": "Weiter", + "next-run": "Nächster Lauf", + "of": "von", + "operation-type": "Operationstyp", + "overall-progress": "Gesamtfortschritt", + "page": "Seite", + "pause-migration": "Migration unterbrechen", + "previous": "Zurück", + "refresh": "Neuladen", + "refresh-monitoring": "Beobachten neuladen", + "remaining-attachments": "Verbleibende Anhänge", + "resume-migration": "Migration fortsetzen", + "run-once": "Einmal ausführen", + "s3-attachments": "S3 Anhänge", + "s3-size": "S3 Größe", + "s3-storage": "S3", + "scanning-status": "Scanstatus", + "schedule": "Zeitplanung", + "search-boards-or-operations": "Durchsuche Bretter oder Vorgänge", + "show-list-on-minicard": "Zeige Liste auf der Minikarte", + "showing": "Gezeigt", + "start-test-operation": "Starte Testvorgang", + "start-time": "Startzeit", + "step-progress": "Durchschreite Fortschritt", + "stop-migration": "Stoppe Migration", + "storage-distribution": "Speicherverteilung", + "system-resources": "Systemressourcen", + "total-attachments": "Gesamte Anhänge", + "total-operations": "Gesamte Vorgänge", + "total-size": "Gesamte Größe", + "unmigrated-boards": "Nicht migrierte Bretter", + "weight": "Gewicht", + "idle": "Untätig", + "complete": "Vollständig", + "cron": "Cron" } diff --git a/imports/i18n/data/el-GR.i18n.json b/imports/i18n/data/el-GR.i18n.json index 039c7019d..efd48c486 100644 --- a/imports/i18n/data/el-GR.i18n.json +++ b/imports/i18n/data/el-GR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "διεγράφη το σχόλιο %s", "activity-receivedDate": "η ημερομηνία λήψης άλλαξε σε %s από %s", "activity-startDate": "η ημερομηνία έναρξης άλλαξε σε %s από %s", + "allboards.starred": "Starred", + "allboards.templates": "Πρότυπα", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "υπέστη επεξεργασία η τιμή της προθεσμίας σε %s από %s", "activity-endDate": "η ημερομηνία λήξης άλλαξε σε %s από %s", "add-attachment": "Προσθήκη Συνημμένου", @@ -190,7 +202,9 @@ "board-view-collapse": "Σύμπτυξη", "board-view-gantt": "Διάγραμμα Gantt", "board-view-lists": "Λίστες", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Ακύρωση", "card-archived": "Αυτή η κάρτα μετακινήθηκε στο Αρχείο.", "board-archived": "Αυτός ο πίνακας μετακινήθηκε στο Αρχείο.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Τίτλος πρώτης κάρτας\", \"description\":\"Περιγραφή πρώτης κάρτας\"}, {\"title\":\"Τίτλος δεύτερης κάρτας\",\"description\":\"Περιγραφή δεύτερης κάρτας\"},{\"title\":\"Τίτλος τελευταίας κάρτας\",\"description\":\"Περιγραφή τελευταίας κάρτας\"} ]", "create": "Δημιουργία", "createBoardPopup-title": "Δημιουργία Πίνακα", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Εισαγωγή πίνακα", "createLabelPopup-title": "Δημιουργία Ετικέτας", "createCustomField": "Δημιουργία Πεδίου", @@ -354,6 +369,10 @@ "custom-field-text": "Κείμενο", "custom-fields": "Προσαρμοσμένα Πεδία", "date": "Ημερομηνία", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Απόρριψη", "default-avatar": "Default avatar", "delete": "Διαγραφή", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Επεξεργασία Ειδοποίησης", "editProfilePopup-title": "Επεξεργασία Προφίλ", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Ένας λογαριασμός δημιουργήθηκε για εσάς στο __siteName__", "email-enrollAccount-text": "Χαίρετε __user__,\n\nΓια να ξεκινήσετε να χρησιμοποιείτε αυτή την υπηρεσία, απλώς κάνετε κλικ στον παρακάτω σύνδεσμο.\n\n__url__\n\nΕυχαριστούμε.", "email-fail": "Η αποστολή του email απέτυχε", @@ -748,6 +768,8 @@ "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": "Διαγραφή Πίνακα", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Προεπιλογή", "defaultdefault": "Προεπιλογή", @@ -755,7 +777,7 @@ "subtask-settings": "Ρυθμίσεις υποεργασιών (subtasks)", "card-settings": "Ρυθμίσεις Κάρτας", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Ρυθμίσεις υποεργασιών (subtasks)", "boardCardSettingsPopup-title": "Ρυθμίσεις Κάρτας", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/el.i18n.json b/imports/i18n/data/el.i18n.json index a28eae94c..0ce0024ac 100644 --- a/imports/i18n/data/el.i18n.json +++ b/imports/i18n/data/el.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "διεγράφη το σχόλιο %s", "activity-receivedDate": "η ημερομηνία λήψης άλλαξε σε %s από %s", "activity-startDate": "η ημερομηνία έναρξης άλλαξε σε %s από %s", + "allboards.starred": "Starred", + "allboards.templates": "Πρότυπα", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "υπέστη επεξεργασία η τιμή της προθεσμίας σε %s από %s", "activity-endDate": "η ημερομηνία λήξης άλλαξε σε %s από %s", "add-attachment": "Προσθήκη Συνημμένου", @@ -190,7 +202,9 @@ "board-view-collapse": "Σύμπτυξη", "board-view-gantt": "Διάγραμμα Gantt", "board-view-lists": "Λίστες", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Ακύρωση", "card-archived": "Αυτή η κάρτα μετακινήθηκε στο Αρχείο.", "board-archived": "Αυτός ο πίνακας μετακινήθηκε στο Αρχείο.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Τίτλος πρώτης κάρτας\", \"description\":\"Περιγραφή πρώτης κάρτας\"}, {\"title\":\"Τίτλος δεύτερης κάρτας\",\"description\":\"Περιγραφή δεύτερης κάρτας\"},{\"title\":\"Τίτλος τελευταίας κάρτας\",\"description\":\"Περιγραφή τελευταίας κάρτας\"} ]", "create": "Δημιουργία", "createBoardPopup-title": "Δημιουργία Πίνακα", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Εισαγωγή πίνακα", "createLabelPopup-title": "Δημιουργία Ετικέτας", "createCustomField": "Δημιουργία Πεδίου", @@ -354,6 +369,10 @@ "custom-field-text": "Κείμενο", "custom-fields": "Προσαρμοσμένα Πεδία", "date": "Ημερομηνία", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Απόρριψη", "default-avatar": "Default avatar", "delete": "Διαγραφή", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Επεξεργασία Ειδοποίησης", "editProfilePopup-title": "Επεξεργασία Προφίλ", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Ένας λογαριασμός δημιουργήθηκε για εσάς στο __siteName__", "email-enrollAccount-text": "Χαίρετε __user__,\n\nΓια να ξεκινήσετε να χρησιμοποιείτε αυτή την υπηρεσία, απλώς κάνετε κλικ στον παρακάτω σύνδεσμο.\n\n__url__\n\nΕυχαριστούμε.", "email-fail": "Η αποστολή του email απέτυχε", @@ -748,6 +768,8 @@ "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": "Διαγραφή Πίνακα", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Προεπιλογή", "defaultdefault": "Προεπιλογή", @@ -755,7 +777,7 @@ "subtask-settings": "Ρυθμίσεις υποεργασιών (subtasks)", "card-settings": "Ρυθμίσεις Κάρτας", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Ρυθμίσεις υποεργασιών (subtasks)", "boardCardSettingsPopup-title": "Ρυθμίσεις Κάρτας", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en-BR.i18n.json b/imports/i18n/data/en-BR.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/en-BR.i18n.json +++ b/imports/i18n/data/en-BR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en-DE.i18n.json b/imports/i18n/data/en-DE.i18n.json index 800ada7ed..7a135972e 100644 --- a/imports/i18n/data/en-DE.i18n.json +++ b/imports/i18n/data/en-DE.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en-GB.i18n.json b/imports/i18n/data/en-GB.i18n.json index e4c60974f..acf3c6934 100644 --- a/imports/i18n/data/en-GB.i18n.json +++ b/imports/i18n/data/en-GB.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -149,7 +161,7 @@ "auto-watch": "Automatically watch boards when they are created", "avatar-too-big": "The avatar is too large (__size__ max)", "back": "Back", - "board-change-color": "Change colour", + "board-change-color": "Change color", "board-change-background-image": "Change Background Image", "board-background-image-url": "Background Image URL", "add-background-image": "Add Background Image", @@ -167,7 +179,7 @@ "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.", "boardChangeColorPopup-title": "Change Board Background", "boardChangeBackgroundImagePopup-title": "Change Background Image", - "allBoardsChangeColorPopup-title": "Change colour", + "allBoardsChangeColorPopup-title": "Change color", "allBoardsChangeBackgroundImagePopup-title": "Change Background Image", "boardChangeTitlePopup-title": "Rename Board", "boardChangeVisibilityPopup-title": "Change Visibility", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,14 +398,15 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", "email-fail-text": "Error trying to send email", "email-invalid": "Invalid email", - "email-invite": "Invite via email", + "email-invite": "Invite via Email", "email-invite-subject": "__inviter__ sent you an invitation", - "email-invite-text": "Dear __user__,\n\n__inviter__ invites you to join board \"__board__\" for collaboration.\n\nPlease follow the link below:\n\n__url__\n\nThanks.", + "email-invite-text": "Dear __user__,\n\n__inviter__ invites you to join board \"__board__\" for collaborations.\n\nPlease follow the link below:\n\n__url__\n\nThanks.", "email-resetPassword-subject": "Reset your password on __siteName__", "email-resetPassword-text": "Hello __user__,\n\nTo reset your password, simply click the link below.\n\n__url__\n\nThanks.", "email-sent": "Email sent", @@ -457,7 +477,7 @@ "filter-to-selection": "Filter to selection", "other-filters-label": "Other Filters", "advanced-filter-label": "Advanced Filter", - "advanced-filter-description": "Advanced Filter allows to write a string containing following operators: == != <= >= && || ( ) A space is used as a separator between the Operators. You can filter for all Custom Fields by typing their names and values. For Example: Field1 == Value1. Note: If fields or values contains spaces, you need to encapsulate them into single quotes. For Example: 'Field 1' == 'Value 1'. For single control characters (' \\\\/) to be skipped, you can use \\\\. For example: Field1 == I\\\\'m. Also you can combine multiple conditions. For Example: F1 == V1 || F1 == V2. Normally all operators are interpreted from left to right. You can change the order by placing brackets. For Example: F1 == V1 && ( F2 == V2 || F2 == V3 ). Also you can search text fields using regex: F1 == /Tes.*/i", + "advanced-filter-description": "Advanced Filter allows to write a string containing following operators: == != <= >= && || ( ) A space is used as a separator between the Operators. You can filter for all Custom Fields by typing their names and values. For Example: Field1 == Value1. Note: If fields or values contains spaces, you need to encapsulate them into single quotes. For Example: 'Field 1' == 'Value 1'. For single control characters (' \\/) to be skipped, you can use \\. For example: Field1 == I\\'m. Also you can combine multiple conditions. For Example: F1 == V1 || F1 == V2. Normally all operators are interpreted from left to right. You can change the order by placing brackets. For Example: F1 == V1 && ( F2 == V2 || F2 == V3 ). Also you can search text fields using regex: F1 == /Tes.*/i", "fullname": "Full Name", "header-logo-title": "Go back to your boards page.", "show-activities": "Show Activities", @@ -520,7 +540,7 @@ "listMorePopup-title": "More", "link-list": "Link to this list", "list-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the list. There is no undo.", - "list-delete-suggest-archive": "You can move a list to Archive to remove it from the board and preserve its activity.", + "list-delete-suggest-archive": "You can move a list to Archive to remove it from the board and preserve the activity.", "lists": "Lists", "swimlanes": "Swimlanes", "log-out": "Log Out", @@ -585,7 +605,7 @@ "rules": "Rules", "search-cards": "Search from card/list titles, descriptions and custom fields on this board", "search-example": "Write text you search and press Enter", - "select-color": "Select Colour", + "select-color": "Select Color", "select-board": "Select Board", "set-wip-limit-value": "Set a limit for the maximum number of tasks in this list", "setWipLimitPopup-title": "Set WIP Limit", @@ -645,10 +665,10 @@ "username": "Username", "import-usernames": "Import Usernames", "view-it": "View it", - "warn-list-archived": "warning: this card is in a list in the Archive", + "warn-list-archived": "warning: this card is in an list at Archive", "watch": "Watch", "watching": "Watching", - "watching-info": "You will be notified of any changes in this board", + "watching-info": "You will be notified of any change in this board", "welcome-board": "Welcome Board", "welcome-swimlane": "Milestone 1", "welcome-list1": "Basics", @@ -686,7 +706,7 @@ "email-smtp-test-subject": "SMTP Test Email", "email-smtp-test-text": "You have successfully sent an email", "error-invitation-code-not-exist": "Invitation code doesn't exist", - "error-notAuthorized": "You are not authorised to view this page.", + "error-notAuthorized": "You are not authorized to view this page.", "webhook-title": "Webhook Name", "webhook-token": "Token (Optional for Authentication)", "outgoing-webhooks": "Outgoing Webhooks", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -909,7 +931,7 @@ "default-authentication-method": "Default Authentication Method", "duplicate-board": "Duplicate Board", "duplicate-board-confirm": "Are you sure you want to duplicate this board?", - "org-number": "The number of organisations is: ", + "org-number": "The number of organizations is: ", "team-number": "The number of teams is: ", "people-number": "The number of people is: ", "swimlaneDeletePopup-title": "Delete Swimlane ?", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en-IT.i18n.json b/imports/i18n/data/en-IT.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/en-IT.i18n.json +++ b/imports/i18n/data/en-IT.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en-MY.i18n.json b/imports/i18n/data/en-MY.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/en-MY.i18n.json +++ b/imports/i18n/data/en-MY.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en-YS.i18n.json b/imports/i18n/data/en-YS.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/en-YS.i18n.json +++ b/imports/i18n/data/en-YS.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en.i18n.json b/imports/i18n/data/en.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/en.i18n.json +++ b/imports/i18n/data/en.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en_AU.i18n.json b/imports/i18n/data/en_AU.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/en_AU.i18n.json +++ b/imports/i18n/data/en_AU.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en_ID.i18n.json b/imports/i18n/data/en_ID.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/en_ID.i18n.json +++ b/imports/i18n/data/en_ID.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en_SG.i18n.json b/imports/i18n/data/en_SG.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/en_SG.i18n.json +++ b/imports/i18n/data/en_SG.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en_TR.i18n.json b/imports/i18n/data/en_TR.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/en_TR.i18n.json +++ b/imports/i18n/data/en_TR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/en_ZA.i18n.json b/imports/i18n/data/en_ZA.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/en_ZA.i18n.json +++ b/imports/i18n/data/en_ZA.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/eo.i18n.json b/imports/i18n/data/eo.i18n.json index b69a847c0..edd730ca6 100644 --- a/imports/i18n/data/eo.i18n.json +++ b/imports/i18n/data/eo.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Listoj", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Krei", "createBoardPopup-title": "Krei tavolon", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Teksto", "custom-fields": "Custom Fields", "date": "Dato", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Redakti profilon", "email": "Retpoŝtadreso", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Malsukcesis sendi retpoŝton", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Defaŭlto", "defaultdefault": "Defaŭlto", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/es-AR.i18n.json b/imports/i18n/data/es-AR.i18n.json index ea2b63bb3..2965baf43 100644 --- a/imports/i18n/data/es-AR.i18n.json +++ b/imports/i18n/data/es-AR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "comentario %s eliminado", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Plantillas", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Agregar Adjunto", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Listas", - "bucket-example": "Como \"Lista de Contenedores\" por ejemplo", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancelar", "card-archived": "Esta tarjeta es movida al Archivo.", "board-archived": "Este tablero es movido al Archivo.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Título de primera tarjeta\", \"description\":\"Descripción de primera tarjeta\"}, {\"title\":\"Título de segunda tarjeta\",\"description\":\"Descripción de segunda tarjeta\"},{\"title\":\"Título de última tarjeta\",\"description\":\"Descripción de última tarjeta\"} ]", "create": "Crear", "createBoardPopup-title": "Crear Tablero", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importar tablero", "createLabelPopup-title": "Crear Etiqueta", "createCustomField": "Crear Campo", @@ -354,6 +369,10 @@ "custom-field-text": "Texto", "custom-fields": "Custom Fields", "date": "Fecha", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Rechazar", "default-avatar": "Avatar por defecto", "delete": "Borrar", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editar Notificación", "editProfilePopup-title": "Editar Perfil", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Una cuenta creada para vos en __siteName__", "email-enrollAccount-text": "Hola __user__,\n\nPara empezar a usar el servicio, simplemente clickeá en el enlace de abajo.\n\n__url__\n\nGracias.", "email-fail": "Fallo envío de email", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/es-CL.i18n.json b/imports/i18n/data/es-CL.i18n.json index 27c74a969..8b2a335e9 100644 --- a/imports/i18n/data/es-CL.i18n.json +++ b/imports/i18n/data/es-CL.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "comentario eliminado", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Plantillas", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Añadir adjunto", @@ -190,7 +202,9 @@ "board-view-collapse": "Contraer", "board-view-gantt": "Gantt", "board-view-lists": "Listas", - "bucket-example": "Como “Cosas por hacer” por ejemplo", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancelar", "card-archived": "Se archivó esta tarjeta", "board-archived": "Se archivó este tablero", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Título de la primera tarjeta\", \"description\":\"Descripción de la primera tarjeta\"}, {\"title\":\"Título de la segunda tarjeta\",\"description\":\"Descripción de la segunda tarjeta\"},{\"title\":\"Título de la última tarjeta\",\"description\":\"Descripción de la última tarjeta\"} ]", "create": "Crear", "createBoardPopup-title": "Crear tablero", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importar un tablero", "createLabelPopup-title": "Crear una etiqueta", "createCustomField": "Crear un campo", @@ -354,6 +369,10 @@ "custom-field-text": "Texto", "custom-fields": "Campos personalizados", "date": "Fecha", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Declinar", "default-avatar": "Avatar por defecto", "delete": "Eliminar", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editar las notificaciones", "editProfilePopup-title": "Editar el perfil", "email": "Correo electrónico", + "email-address": "Email Address", "email-enrollAccount-subject": "Cuenta creada en __siteName__", "email-enrollAccount-text": "Hola __user__,\n\nPara empezar a utilizar el servicio, simplemente haz clic en el siguiente enlace.\n\n__url__\n\nGracias.", "email-fail": "Error al enviar el correo", @@ -748,6 +768,8 @@ "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?", "delete-board": "Eliminar el tablero", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtareas para el tablero __board__", "default": "Por defecto", "defaultdefault": "Por defecto", @@ -755,7 +777,7 @@ "subtask-settings": "Preferencias de las subtareas", "card-settings": "Preferencias de la tarjeta", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Preferencias de las subtareas del tablero", + "boardSubtaskSettingsPopup-title": "Preferencias de las subtareas", "boardCardSettingsPopup-title": "Preferencias de la tarjeta", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Depositar subtareas en este tablero:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completada", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/es-LA.i18n.json b/imports/i18n/data/es-LA.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/es-LA.i18n.json +++ b/imports/i18n/data/es-LA.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/es-MX.i18n.json b/imports/i18n/data/es-MX.i18n.json index 8a6e6586b..b2039e95e 100644 --- a/imports/i18n/data/es-MX.i18n.json +++ b/imports/i18n/data/es-MX.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "comentario eliminado %s", "activity-receivedDate": "fecha de recepción editada para %s de %s", "activity-startDate": "fecha de inicio editada a %s de %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "fecha de vencimiento editada a %s de %s", "activity-endDate": "editada la fecha de finalización a %s de %s", "add-attachment": "Agregar adjunto", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/es-PE.i18n.json b/imports/i18n/data/es-PE.i18n.json index 395f86e2a..8d0e4c283 100644 --- a/imports/i18n/data/es-PE.i18n.json +++ b/imports/i18n/data/es-PE.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "comentario eliminado", "activity-receivedDate": "editada la fecha de recepción a %s de %s", "activity-startDate": "editada la fecha de inicio a %s de %s", + "allboards.starred": "Starred", + "allboards.templates": "Plantillas", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "editada la fecha de vencimiento a %s de %s", "activity-endDate": "editada la fecha de finalización a %s de %s", "add-attachment": "Agregar adjunto", @@ -190,7 +202,9 @@ "board-view-collapse": "Contraer", "board-view-gantt": "Gantt", "board-view-lists": "Listas", - "bucket-example": "Como «Cosas por hacer» por ejemplo", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancelar", "card-archived": "Se archivó esta tarjeta", "board-archived": "Se archivó este tablero", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Título de la primera tarjeta\", \"description\":\"Descripción de la primera tarjeta\"}, {\"title\":\"Título de la segunda tarjeta\",\"description\":\"Descripción de la segunda tarjeta\"},{\"title\":\"Título de la última tarjeta\",\"description\":\"Descripción de la última tarjeta\"} ]", "create": "Crear", "createBoardPopup-title": "Crear tablero", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importar un tablero", "createLabelPopup-title": "Crear una etiqueta", "createCustomField": "Crear un campo", @@ -354,6 +369,10 @@ "custom-field-text": "Texto", "custom-fields": "Campos personalizados", "date": "Fecha", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Declinar", "default-avatar": "Avatar por defecto", "delete": "Eliminar", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editar las notificaciones", "editProfilePopup-title": "Editar el perfil", "email": "Correo electrónico", + "email-address": "Email Address", "email-enrollAccount-subject": "Cuenta creada en __siteName__", "email-enrollAccount-text": "Hola __user__,\n\nPara empezar a utilizar el servicio, simplemente haga clic en el siguiente enlace.\n\n__url__\n\nGracias.", "email-fail": "Error al enviar el correo", @@ -748,6 +768,8 @@ "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?", "delete-board": "Eliminar el tablero", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtareas para el tablero __board__", "default": "Por defecto", "defaultdefault": "Por defecto", @@ -755,7 +777,7 @@ "subtask-settings": "Configuración de subtareas", "card-settings": "Configuración de tarjeta", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Configuración de subtareas del tablero", + "boardSubtaskSettingsPopup-title": "Configuración de subtareas", "boardCardSettingsPopup-title": "Configuración de tarjeta", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Depositar subtareas en este tablero:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "Todos los usuarios", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Estado", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completada", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "de", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/es-PY.i18n.json b/imports/i18n/data/es-PY.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/es-PY.i18n.json +++ b/imports/i18n/data/es-PY.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/es.i18n.json b/imports/i18n/data/es.i18n.json index 6d1fdff27..27be64c0c 100644 --- a/imports/i18n/data/es.i18n.json +++ b/imports/i18n/data/es.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "comentario eliminado", "activity-receivedDate": "editada la fecha de recepción a %s de %s", "activity-startDate": "editada la fecha de inicio a %s de %s", + "allboards.starred": "Starred", + "allboards.templates": "Plantillas", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "editada la fecha de vencimiento a %s de %s", "activity-endDate": "editada la fecha de finalización a %s de %s", "add-attachment": "Añadir adjunto", @@ -125,7 +137,7 @@ "archive": "Archivar", "archive-all": "Archivar todo", "archive-board": "Archivar este tablero", - "archive-board-confirm": "Are you sure you want to archive this board?", + "archive-board-confirm": "¿Estás seguro que quieres archivar este tablero?", "archive-card": "Archivar esta tarjeta", "archive-list": "Archivar esta lista", "archive-swimlane": "Archivar este carril", @@ -177,20 +189,22 @@ "boardChangeViewPopup-title": "Vista del tablero", "boards": "Tableros", "board-view": "Vista del tablero", - "desktop-mode": "Desktop Mode", - "mobile-mode": "Mobile Mode", - "mobile-desktop-toggle": "Toggle between Mobile and Desktop Mode", - "zoom-in": "Zoom In", - "zoom-out": "Zoom Out", - "click-to-change-zoom": "Click to change zoom level", - "zoom-level": "Zoom Level", - "enter-zoom-level": "Enter zoom level (50-300%):", + "desktop-mode": "Modo de Escritorio", + "mobile-mode": "Modo Móvil", + "mobile-desktop-toggle": "Alterna entre el Modo Móvil y el Modo de Escritorio", + "zoom-in": "Acercar", + "zoom-out": "Alejar", + "click-to-change-zoom": "Haz clic para cambiar el nivel de zoom", + "zoom-level": "Nivel de zoom", + "enter-zoom-level": "Introduzca el nivel de zoom (50-300%):", "board-view-cal": "Calendario", "board-view-swimlanes": "Carriles", "board-view-collapse": "Contraer", "board-view-gantt": "Gantt", "board-view-lists": "Listas", - "bucket-example": "Como “Cosas por hacer” por ejemplo", + "bucket-example": "Mes anterior", + "calendar-previous-month-label": "Mes anterior", + "calendar-next-month-label": "Mes siguiente", "cancel": "Cancelar", "card-archived": "Se archivó esta tarjeta", "board-archived": "Se archivó este tablero", @@ -314,15 +328,15 @@ "comment-placeholder": "Escribir comentario", "comment-only": "Sólo comentarios", "comment-only-desc": "Solo puedes comentar en las tarjetas.", - "comment-delete": "¿Seguro que quieres borrar el comentario?", + "comment-delete": "¿Estás seguro que quieres borrar el comentario?", "deleteCommentPopup-title": "¿Borrar comentario?", "no-comments": "No hay comentarios", "no-comments-desc": "No se pueden mostrar comentarios ni actividades.", "worker": "Trabajador", "worker-desc": "Solo puede mover tarjetas, asignarse a la tarjeta y comentar.", "computer": "el ordenador", - "confirm-subtask-delete-popup": "¿Seguro que quieres eliminar la subtarea?", - "confirm-checklist-delete-popup": "¿Está seguro de querer eliminar la lista de tareas?", + "confirm-subtask-delete-popup": "¿Estás seguro que quieres eliminar la subtarea?", + "confirm-checklist-delete-popup": "¿Estás seguro de querer eliminar la lista de tareas?", "subtaskDeletePopup-title": "¿Borrar subtarea?", "checklistDeletePopup-title": "¿Borrar la lista de tareas?", "copy-card-link-to-clipboard": "Copiar el enlace de la tarjeta al portapapeles", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Título de la primera tarjeta\", \"description\":\"Descripción de la primera tarjeta\"}, {\"title\":\"Título de la segunda tarjeta\",\"description\":\"Descripción de la segunda tarjeta\"},{\"title\":\"Título de la última tarjeta\",\"description\":\"Descripción de la última tarjeta\"} ]", "create": "Crear", "createBoardPopup-title": "Crear tablero", + "createTemplateContainerPopup-title": "añadir plantilla de contenedor", "chooseBoardSourcePopup-title": "Importar un tablero", "createLabelPopup-title": "Crear una etiqueta", "createCustomField": "Crear un campo", @@ -354,6 +369,10 @@ "custom-field-text": "Texto", "custom-fields": "Campos personalizados", "date": "Fecha", + "date-format": "Formato de fecha", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Declinar", "default-avatar": "Avatar por defecto", "delete": "Eliminar", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editar las notificaciones", "editProfilePopup-title": "Editar el perfil", "email": "Correo electrónico", + "email-address": "Email Address", "email-enrollAccount-subject": "Cuenta creada en __siteName__", "email-enrollAccount-text": "Hola __user__,\n\nPara empezar a utilizar el servicio, simplemente haz clic en el siguiente enlace.\n\n__url__\n\nGracias.", "email-fail": "Error al enviar el correo", @@ -631,9 +651,9 @@ "upload": "Cargar", "upload-avatar": "Cargar un avatar", "uploaded-avatar": "Avatar cargado", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "Subiendo archivos", + "upload-failed": "Fallo al subir", + "upload-completed": "Subida completada", "custom-top-left-corner-logo-image-url": "Personalizar la URL del logotipo en la esquina superior izquierda", "custom-top-left-corner-logo-link-url": "Personalizar el enlace del logotipo de la esquina superior izquierda", "custom-top-left-corner-logo-height": "Altura personalizada del logo de la esquina superior izquierda. Por defecto: 27", @@ -748,6 +768,8 @@ "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?", "delete-board": "Eliminar el tablero", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtareas para el tablero __board__", "default": "Por defecto", "defaultdefault": "Por defecto", @@ -755,9 +777,9 @@ "subtask-settings": "Preferencias de las subtareas", "card-settings": "Preferencias de la tarjeta", "minicard-settings": "Configuración de minitarjeta", - "boardSubtaskSettingsPopup-title": "Preferencias de las subtareas del tablero", + "boardSubtaskSettingsPopup-title": "Preferencias de las subtareas", "boardCardSettingsPopup-title": "Preferencias de la tarjeta", - "boardMinicardSettingsPopup-title": "Minicard Settings", + "boardMinicardSettingsPopup-title": "Preferencias de minitarjetas", "deposit-subtasks-board": "Depositar subtareas en este tablero:", "deposit-subtasks-list": "Lista de destino para subtareas depositadas aquí:", "show-parent-in-minicard": "Mostrar el padre en una minitarjeta:", @@ -908,7 +930,7 @@ "oidc-button-text": "Customize the OIDC button text", "default-authentication-method": "Método de autenticación por defecto", "duplicate-board": "Duplicar tablero", - "duplicate-board-confirm": "Are you sure you want to duplicate this board?", + "duplicate-board-confirm": "¿Estás seguro de querer duplicar este tablero?", "org-number": "El número de organizaciones es:", "team-number": "El número de equipos es:", "people-number": "El número de personas es:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Yo", "dueCardsViewChange-choice-all": "Todos los usuarios", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Tarjetas Rotas", "board-title-not-found": "Tablero '%s' no encontrado.", "swimlane-title-not-found": "Carril '%s' no encontrado.", @@ -1227,14 +1251,14 @@ "subtaskActionsPopup-title": "Acciones de la Subtarea", "attachmentActionsPopup-title": "Acciones de Adhesión", "attachment-move-storage-fs": "Mover el archivo adjunto al sistema de archivos", - "attachment-move-storage-gridfs": "Mover adjunto a GridFS", - "attachment-move-storage-s3": "Move attachment to S3", + "attachment-move-storage-gridfs": "Mover el adjunto a GridFS", + "attachment-move-storage-s3": "Mover el adjunto a S3", "attachment-move": "Mover el Adjunto", "move-all-attachments-to-fs": "Mover todos los archivos adjuntos al sistema de archivos", "move-all-attachments-to-gridfs": "Mover todos los adjuntos a GridFS", "move-all-attachments-to-s3": "Move all attachments to S3", "move-all-attachments-of-board-to-fs": "Mover todos los adjuntos del tablero al sistema de archivos", - "move-all-attachments-of-board-to-gridfs": "Move all attachments of board to GridFS", + "move-all-attachments-of-board-to-gridfs": "Mover todos los adjuntos del tablero a GridFS", "move-all-attachments-of-board-to-s3": "Mover todos los adjuntos del tablero a S3", "path": "Ruta", "version-name": "Nombre de la versión", @@ -1284,34 +1308,272 @@ "accessibility-info-not-added-yet": "Accessibility info has not been added yet", "accessibility-title": "Accessibility title", "accessibility-content": "Contenido de accesibilidad", - "accounts-lockout-settings": "Brute Force Protection Settings", - "accounts-lockout-info": "These settings control how login attempts are protected against brute force attacks.", - "accounts-lockout-known-users": "Settings for known users (correct username, wrong password)", - "accounts-lockout-unknown-users": "Settings for unknown users (non-existent username)", + "accounts-lockout-settings": "Configuración de protección de ataques de fuerza bruta", + "accounts-lockout-info": "Estas opciones de configuración controlan cómo los inicios de sesión se protegen de ataques de fuerza bruta.", + "accounts-lockout-known-users": "Configuración para usuarios conocidos (nombre de usuario correcto, contraseña incorrecta)", + "accounts-lockout-unknown-users": "Configuración para usuarios desconocidos (nombre de usuario desconocido)", "accounts-lockout-failures-before": "Failures before lockout", "accounts-lockout-period": "Lockout period (seconds)", "accounts-lockout-failure-window": "Failure window (seconds)", - "accounts-lockout-settings-updated": "Brute force protection settings have been updated", + "accounts-lockout-settings-updated": "La configuración de protección de fuerza bruta se ha actualizado", "accounts-lockout-locked-users": "Locked Users", - "accounts-lockout-locked-users-info": "Users currently locked out due to too many failed login attempts", + "accounts-lockout-locked-users-info": "Usuarios actualmente bloqueados debido a demasiados intentos fallidos de inicio de sesión", "accounts-lockout-no-locked-users": "There are currently no locked users", - "accounts-lockout-failed-attempts": "Failed Attempts", + "accounts-lockout-failed-attempts": "Intentos fallidos", "accounts-lockout-remaining-time": "Remaining Time", "accounts-lockout-user-unlocked": "User has been unlocked successfully", - "accounts-lockout-confirm-unlock": "Are you sure you want to unlock this user?", - "accounts-lockout-confirm-unlock-all": "Are you sure you want to unlock all locked users?", + "accounts-lockout-confirm-unlock": "¿Estas seguro de querer desbloquear a este usuario?", + "accounts-lockout-confirm-unlock-all": "¿Estás seguro de querer desbloquear todos los usuarios bloqueados?", "accounts-lockout-show-locked-users": "Show locked users only", - "accounts-lockout-user-locked": "User is locked", - "accounts-lockout-click-to-unlock": "Click to unlock this user", + "accounts-lockout-user-locked": "El usuario está bloqueado", + "accounts-lockout-click-to-unlock": "Haz clic para desbloquear a este usuario", "accounts-lockout-status": "Estado", "admin-people-filter-show": "Show:", "admin-people-filter-all": "Todos los usuarios", - "admin-people-filter-locked": "Locked Users Only", + "admin-people-filter-locked": "Solo usuarios bloqueados", "admin-people-filter-active": "Activo", "admin-people-filter-inactive": "Not Active", "admin-people-active-status": "Active Status", - "admin-people-user-active": "User is active - click to deactivate", - "admin-people-user-inactive": "User is inactive - click to activate", + "admin-people-user-active": "El usuario está activo - haz clic para desactivarlo", + "admin-people-user-inactive": "El usuario está inactivo - haz clic para activarlo", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Desbloquea a todos", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Configuración de almacenamiento de adjuntos", + "attachments-path": "Ruta de adjuntos", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Fallo al programar el archivo del tablero", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Fallo al programar la copia de respaldo del tablero", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Fallo al programar el borrado del tablero", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "¿Estás seguro de querer borrar este Cron Job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Fallo al pausar las migraciones", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Proceso de migración", + "migration-start-failed": "Fallo al iniciar las migraciones", + "migration-started": "Las migraciones se han iniciado correctamente", + "migration-status": "Estado de migración", + "migration-stop-confirm": "¿Estás seguro de querer detener todas las migraciones?", + "migration-stop-failed": "Fallo al detener las migraciones", + "migration-stopped": "Las migraciones se han detenido correctamente", + "mongodb-gridfs-storage": "Almacenamiento MongoDB GridFS", + "pause-all-migrations": "Pausar todas las migraciones", + "s3-access-key": "Clave de acceso de S3", + "s3-access-key-description": "Clave de acceso de AWS S3 para autentificación", + "s3-access-key-placeholder": "Introduzca la clave de acceso de S3", + "s3-bucket": "Bucket S3", + "s3-bucket-description": "Nombre del Bucket S3 para guardar los archivos", + "s3-connection-failed": "La conexión S3 ha fallado", + "s3-connection-success": "Conexión a S3 exitosa", + "s3-enabled": "Habilitado S3", + "s3-enabled-description": "Usar AWS S3 o MinIO para almacenamiento de archivos", + "s3-endpoint": "Endpoint S3", + "s3-endpoint-description": "URL del Endpoint S3 (por ejemplo, s3.amazonaws.com o minio.example.com)", + "s3-minio-storage": "Almacenamiento S3/MinIO", + "s3-port": "Puerto S3", + "s3-port-description": "Número de puerto del Endpoint S3", + "s3-region": "Región S3", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Fallo al guardar la configuración de S3", + "s3-settings-saved": "La configuración de S3 se ha guardado correctamente", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Guardar configuración de S3", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Completado", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Estado", + "migration-progress-details": "Detalles", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completada", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duración", + "errors": "Errores", + "estimated-time-remaining": "Tiempo restante estimado", + "every-1-day": "Cada día", + "every-1-hour": "Cada hora", + "every-1-minute": "Cada minuto", + "every-10-minutes": "Cada 10 minutos", + "every-30-minutes": "Cada 30 minutos", + "every-5-minutes": "Cada 5 minutos", + "every-6-hours": "Cada 6 horas", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "de", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Peso", + "idle": "Inactivo", + "complete": "Completado", + "cron": "Programación" } diff --git a/imports/i18n/data/es_CO.i18n.json b/imports/i18n/data/es_CO.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/es_CO.i18n.json +++ b/imports/i18n/data/es_CO.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/et-EE.i18n.json b/imports/i18n/data/et-EE.i18n.json index 892c60719..d16e2a033 100644 --- a/imports/i18n/data/et-EE.i18n.json +++ b/imports/i18n/data/et-EE.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "kustutatud kommentaar %s", "activity-receivedDate": "redigeeritud saabunud kuupäev %s-i %s-i", "activity-startDate": "redigeeritud alguskuupäev %s-i %s-i alguskuupäevaks", + "allboards.starred": "Starred", + "allboards.templates": "Mallid", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "redigeeritud tähtaeg on %s of %s", "activity-endDate": "redigeeritud lõpukuupäev %s-i %s-i lõpukuupäevaks", "add-attachment": "Lisa lisa", @@ -190,7 +202,9 @@ "board-view-collapse": "Kokkupõrge", "board-view-gantt": "Gantt", "board-view-lists": "Loetelud", - "bucket-example": "Nagu näiteks \"Bucket List\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Tühista", "card-archived": "See kaart on viidud arhiivi.", "board-archived": "See foorum on viidud arhiivi.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": {\"title\": \"First card title\", \"description\": \"First card description\"}, {\"title\": \"Second card title\", \"description\": \"Second card description\"},{\"title\": \"Last card title\", \"description\": \"Last card description\"}, {\"title\": \"Last card title\", \"description\": \"Last card description\"} ]", "create": "Loo", "createBoardPopup-title": "Loo juhatus", + "createTemplateContainerPopup-title": "Malli konteineri lisamine", "chooseBoardSourcePopup-title": "Impordilaua", "createLabelPopup-title": "Loo silt", "createCustomField": "Loo väli", @@ -354,6 +369,10 @@ "custom-field-text": "Tekst", "custom-fields": "Kohandatud väljad", "date": "Kuupäev", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Langus", "default-avatar": "Default avatar", "delete": "Kustuta", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Teavituse muutmine", "editProfilePopup-title": "Profiilide muutmine", "email": "E-post", + "email-address": "Email Address", "email-enrollAccount-subject": "Teie jaoks loodud konto __siteName__", "email-enrollAccount-text": "Tere __user__,\n\nTeenuse kasutamise alustamiseks klõpsake lihtsalt alloleval lingil.\n\n__url__\n\nTänan teid.", "email-fail": "E-posti saatmine ebaõnnestus", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Kõik nimekirjad, kaardid, sildid ja tegevused kustutatakse ja te ei saa tahvli sisu taastada. Tühistamist ei ole võimalik teha.", "boardDeletePopup-title": "Kustuta juhatus?", "delete-board": "Kustuta juhatus", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Juhatuse __board__ alamülesanded", "default": "Vaikimisi", "defaultdefault": "Vaikimisi", @@ -755,7 +777,7 @@ "subtask-settings": "Alaülesannete seaded", "card-settings": "Kaardi seaded", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Juhatuse alamülesannete seaded", + "boardSubtaskSettingsPopup-title": "Alaülesannete seaded", "boardCardSettingsPopup-title": "Kaardi seaded", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Hoiustage alamülesanded sellele tahvlile:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Mina", "dueCardsViewChange-choice-all": "Kõik kasutajad", "dueCardsViewChange-choice-all-description": "Näitab kõik lõpetamata kaardid, millel on *Tähtaeg* ja mille jaoks kasutajal on luba.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Purunenud kaardid", "board-title-not-found": "Lauda '%s' ei leitud.", "swimlane-title-not-found": "Swimlane '%s' ei leitud.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Staatus", + "migration-progress-details": "Üksikasjad", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Lõpetatud", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "/", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/eu.i18n.json b/imports/i18n/data/eu.i18n.json index 1dab67354..228365b30 100644 --- a/imports/i18n/data/eu.i18n.json +++ b/imports/i18n/data/eu.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "%s iruzkina ezabatu da", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Txantiloiak", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Gehitu eranskina", @@ -190,7 +202,9 @@ "board-view-collapse": "Tolestu", "board-view-gantt": "Gantt", "board-view-lists": "Zerrendak", - "bucket-example": "Esaterako \"Pertz zerrenda\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Utzi", "card-archived": "Txartel hau biltegira eraman da", "board-archived": "Arbel hau biltegira eraman da", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Sortu", "createBoardPopup-title": "Sortu arbela", + "createTemplateContainerPopup-title": "Gehitu txantiloien edukiontzia", "chooseBoardSourcePopup-title": "Inportatu arbela", "createLabelPopup-title": "Sortu etiketa", "createCustomField": "Sortu eremua", @@ -354,6 +369,10 @@ "custom-field-text": "Testua", "custom-fields": "Eremu pertsonalizatuak", "date": "Data", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Ukatu", "default-avatar": "Lehenetsitako avatarra", "delete": "Ezabatu", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editatu jakinarazpena", "editProfilePopup-title": "Editatu profila", "email": "e-posta", + "email-address": "Email Address", "email-enrollAccount-subject": "Kontu bat sortu zaizu __siteName__ gunean", "email-enrollAccount-text": "Kaixo __user__,\n\nZerbitzua erabiltzen hasteko, egin klik beheko loturan.\n\n__url__\n\nEskerrik asko.", "email-fail": "E-posta bidalketak huts egin du", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Zerrenda, txartel eta aktibitate guztiak ezabatuko dira eta ezingo dituzu berreskuratu arbelaren edukiak. Atzera bueltarik ez du.", "boardDeletePopup-title": "Delete Board?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Lehenetsia", "defaultdefault": "Lehenetsia", @@ -755,7 +777,7 @@ "subtask-settings": "Azpiatazaren ezarpenak", "card-settings": "Txartelaren ezarpenak", "minicard-settings": "Minitxartelaren ezarpenak", - "boardSubtaskSettingsPopup-title": "Arbeleko azpiatazaren ezarpenak", + "boardSubtaskSettingsPopup-title": "Azpiatazaren ezarpenak", "boardCardSettingsPopup-title": "Txartelaren ezarpenak", "boardMinicardSettingsPopup-title": "Minitxartelaren ezarpenak", "deposit-subtasks-board": "Ipini azpiatazak arbel honetan:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Erabiltzaileak baimena duen arbeletako *Epemuga* data duten txartel osatugabe guztiak erakusten ditu.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Puskatutako txartelak", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "Erabiltzailea aktiboa dago - egin klik desaktibatzeko", "admin-people-user-inactive": "Erabiltzailea ez dago aktiboa - egin klik aktibatzeko", "accounts-lockout-all-users-unlocked": "Blokeatutako erabiltzaile guztiak desblokeatu dira", - "accounts-lockout-unlock-all": "Desblokeatu guztiak" + "accounts-lockout-unlock-all": "Desblokeatu guztiak", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/fa-IR.i18n.json b/imports/i18n/data/fa-IR.i18n.json index 15ad2e194..049e398af 100644 --- a/imports/i18n/data/fa-IR.i18n.json +++ b/imports/i18n/data/fa-IR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "%s نظر حذف شد", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "قالب‌ها", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "افزودن ضمیمه", @@ -190,7 +202,9 @@ "board-view-collapse": "جمع کردن", "board-view-gantt": "گانت", "board-view-lists": "لیست‌ها", - "bucket-example": "برای مثال چیزی شبیه \"لیست سطل\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "انصراف", "card-archived": "این کارت به آرشیو انتقال داده‌شده‌است.", "board-archived": "این برد به آرشیو انتقال داده‌شده‌است.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "ایجاد", "createBoardPopup-title": "ایجاد برد", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "وارد کردن برد", "createLabelPopup-title": "ایجاد لیبل", "createCustomField": "ایجاد فیلد", @@ -354,6 +369,10 @@ "custom-field-text": "متن", "custom-fields": "فیلدهای شخصی", "date": "تاریخ", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "رد", "default-avatar": "آواتار پیش‌فرض", "delete": "حذف", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "اصلاح اعلان", "editProfilePopup-title": "ویرایش پروفایل", "email": "پست الکترونیک", + "email-address": "Email Address", "email-enrollAccount-subject": "یک حساب کاربری برای شما در __siteName__ ایجاد شد", "email-enrollAccount-text": "سلام __user__ \nبرای شروع به استفاده از این سرویس برروی آدرس زیر کلیک کنید.\n__url__\nبا تشکر.", "email-fail": "عدم موفقیت در فرستادن رایانامه", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "تمام لیست ها، کارت ها، لیبل ها و فعالیت ها حذف خواهند شد و شما نمی توانید محتوای برد را بازیابی کنید. هیچ واکنشی وجود ندارد", "boardDeletePopup-title": "حذف برد؟", "delete-board": "حذف برد", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "زیروظایفِ برد __board__", "default": "پیش‌فرض", "defaultdefault": "پیش‌فرض", @@ -755,7 +777,7 @@ "subtask-settings": "تنظیمات زیروظایف", "card-settings": "تنظیمات کارت", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "تنظیمات زیروظایف برد", + "boardSubtaskSettingsPopup-title": "تنظیمات زیروظایف", "boardCardSettingsPopup-title": "تنظیمات کارت", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "افزودن ریزکار به برد:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "من", "dueCardsViewChange-choice-all": "تمام کاربران", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "کارت های شکسته", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "وضعیت", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "تمام شده", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "از", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/fa.i18n.json b/imports/i18n/data/fa.i18n.json index 68548f902..0d48e1299 100644 --- a/imports/i18n/data/fa.i18n.json +++ b/imports/i18n/data/fa.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "%s نظر حذف شد", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "قالب‌ها", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "افزودن ضمیمه", @@ -190,7 +202,9 @@ "board-view-collapse": "جمع کردن", "board-view-gantt": "گانت", "board-view-lists": "لیست‌ها", - "bucket-example": "برای مثال چیزی شبیه \"لیست سطل\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "انصراف", "card-archived": "این کارت به آرشیو انتقال داده‌شده‌است.", "board-archived": "این برد به آرشیو انتقال داده‌شده‌است.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "ایجاد", "createBoardPopup-title": "ایجاد برد", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "وارد کردن برد", "createLabelPopup-title": "ایجاد لیبل", "createCustomField": "ایجاد فیلد", @@ -354,6 +369,10 @@ "custom-field-text": "متن", "custom-fields": "فیلدهای شخصی", "date": "تاریخ", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "رد", "default-avatar": "آواتار پیش‌فرض", "delete": "حذف", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "اصلاح اعلان", "editProfilePopup-title": "ویرایش پروفایل", "email": "پست الکترونیک", + "email-address": "Email Address", "email-enrollAccount-subject": "یک حساب کاربری برای شما در __siteName__ ایجاد شد", "email-enrollAccount-text": "سلام __user__ \nبرای شروع به استفاده از این سرویس برروی آدرس زیر کلیک کنید.\n__url__\nبا تشکر.", "email-fail": "عدم موفقیت در فرستادن رایانامه", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "تمام لیست ها، کارت ها، لیبل ها و فعالیت ها حذف خواهند شد و شما نمی توانید محتوای برد را بازیابی کنید. هیچ واکنشی وجود ندارد", "boardDeletePopup-title": "حذف برد؟", "delete-board": "حذف برد", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "زیروظایفِ برد __board__", "default": "پیش‌فرض", "defaultdefault": "پیش‌فرض", @@ -755,7 +777,7 @@ "subtask-settings": "تنظیمات زیروظایف", "card-settings": "تنظیمات کارت", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "تنظیمات زیروظایف برد", + "boardSubtaskSettingsPopup-title": "تنظیمات زیروظایف", "boardCardSettingsPopup-title": "تنظیمات کارت", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "افزودن ریزکار به برد:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "من", "dueCardsViewChange-choice-all": "تمام کاربران", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "کارت های شکسته", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "وضعیت", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "تمام شده", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "از", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/fi.i18n.json b/imports/i18n/data/fi.i18n.json index b392c77bd..6a4c693e1 100644 --- a/imports/i18n/data/fi.i18n.json +++ b/imports/i18n/data/fi.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "poisti kommentin %s", "activity-receivedDate": "muokkasi vastaanotettu päiväksi %s / %s", "activity-startDate": "muokkasi aloituspäiväksi %s / %s", + "allboards.starred": "Suosikki", + "allboards.templates": "Mallit", + "allboards.remaining": "Jäljellä", + "allboards.workspaces": "Työtilat", + "allboards.add-workspace": "Lisää työtila", + "allboards.add-workspace-prompt": "Työtilan nimi", + "allboards.add-subworkspace": "Lisää alityötila", + "allboards.add-subworkspace-prompt": "Alityötilan nimi", + "allboards.edit-workspace": "Muokkaa työtilaa", + "allboards.edit-workspace-name": "Työtilan nimi", + "allboards.edit-workspace-icon": "Työtilan ikoni (markdown)", + "multi-selection-active": "Valitse taulut napsauttamalla valintaruutuja", "activity-dueDate": "muokkasi eräpäiväksi %s / %s", "activity-endDate": "muokkasi loppumispäiväksi %s / %s", "add-attachment": "Lisää liite", @@ -190,7 +202,9 @@ "board-view-collapse": "Pienennä", "board-view-gantt": "Gantt", "board-view-lists": "Listat", - "bucket-example": "Kuten “Laatikko lista” esimerkiksi", + "bucket-example": "Kuten esimerkiksi \"Kauha lista\"", + "calendar-previous-month-label": "Edellinen kuukausi", + "calendar-next-month-label": "Seuraava kuukausi", "cancel": "Peruuta", "card-archived": "Tämä kortti on siirretty Arkistoon.", "board-archived": "Tämä taulu on siirretty Arkistoon.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Ensimmäisen kortin otsikko\", \"description\":\"Ensimmäisen kortin kuvaus\"}, {\"title\":\"Toisen kortin otsikko\",\"description\":\"Toisen kortin kuvaus\"},{\"title\":\"Viimeisen kortin otsikko\",\"description\":\"Viimeisen kortin kuvaus\"} ]", "create": "Luo", "createBoardPopup-title": "Luo taulu", + "createTemplateContainerPopup-title": "Lisää mallikontti", "chooseBoardSourcePopup-title": "Tuo taulu", "createLabelPopup-title": "Luo nimilappu", "createCustomField": "Luo kenttä", @@ -354,6 +369,10 @@ "custom-field-text": "Teksti", "custom-fields": "Mukautetut kentät", "date": "Päivämäärä", + "date-format": "Päivämäärämuoto", + "date-format-yyyy-mm-dd": "VVVV-KK-PP", + "date-format-dd-mm-yyyy": "PP-KK-VVVV", + "date-format-mm-dd-yyyy": "KK-PP-VVVV", "decline": "Kieltäydy", "default-avatar": "Oletusprofiilikuva", "delete": "Poista", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Muokkaa ilmoituksia", "editProfilePopup-title": "Muokkaa profiilia", "email": "Sähköposti", + "email-address": "Sähköpostiosoite", "email-enrollAccount-subject": "Sinulle on luotu tili palveluun __siteName__", "email-enrollAccount-text": "Hei __user__,\n\nKlikkaa alla olevaa linkkiä aloittaaksesi palvelun käytön.\n\n__url__\n\nKiitos.", "email-fail": "Sähköpostin lähettäminen epäonnistui", @@ -748,6 +768,8 @@ "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?", "delete-board": "Poista taulu", + "delete-duplicate-lists": "Poista ylimääräiset lista kopiot", + "delete-duplicate-lists-confirm": "Oletko varma? Tämä poistaa kaikki ylimääräiset lista kopiot, joilla on sama nimi ja jotka eivät sisällä kortteja.", "default-subtasks-board": "Alitehtävät taululle __board__", "default": "Oletus", "defaultdefault": "Oletus", @@ -755,7 +777,7 @@ "subtask-settings": "Alitehtävä-asetukset", "card-settings": "Kortin asetukset", "minicard-settings": "Minikortin asetukset", - "boardSubtaskSettingsPopup-title": "Taulualitehtävien asetukset", + "boardSubtaskSettingsPopup-title": "Alitehtävä-asetukset", "boardCardSettingsPopup-title": "Kortin asetukset", "boardMinicardSettingsPopup-title": "Minikortin asetukset", "deposit-subtasks-board": "Talleta alitehtävät tälle taululle:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Minä", "dueCardsViewChange-choice-all": "Kaikki käyttäjät", "dueCardsViewChange-choice-all-description": "Näyttää kaikki keskeneräiset kortit joilla on *eräpäivä* tauluilta joihin käyttäjällä on oikeudet.", + "dueCards-noResults-title": "Erääntyviä kortteja ei löytynyt", + "dueCards-noResults-description": "Sinulla ei ole tällä hetkellä yhtään erääntyvää korttia.", "broken-cards": "Rikkinäiset kortit", "board-title-not-found": "Taulua '%s' ei löytynyt.", "swimlane-title-not-found": "Uimarataa '%s' ei löytynyt.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "Käyttäjä on aktiivinen - napsauttamalla ei-aktiiviseksi", "admin-people-user-inactive": "Käyttäjä ei ole aktiivinen - napsauta aktivoidaksesi", "accounts-lockout-all-users-unlocked": "Kaikki lukitut käyttäjät on avattu", - "accounts-lockout-unlock-all": "Avaa lukitus kaikista" + "accounts-lockout-unlock-all": "Avaa lukitus kaikista", + "active-cron-jobs": "Aktiiviset ajastetut työt", + "add-cron-job": "Lisää ajastettu työ", + "add-cron-job-placeholder": "Ajastetun työn lisääminen tulossa pian", + "attachment-storage-configuration": "Liitteiden tallennuskonfiguraatio", + "attachments-path": "Liitteiden polku", + "attachments-path-description": "Polku jossa liitetiedostot tallennetaan", + "avatars-path": "Profiilikuvien polku", + "avatars-path-description": "Polku jossa profiilikuvat tallennetaan", + "board-archive-failed": "Taulun arkistointi epäonnistui", + "board-archive-scheduled": "Taulun arkistointi ajastettu onnistuneesti", + "board-backup-failed": "Taulun varmuuskopiointi epäonnistui", + "board-backup-scheduled": "Taulun varmuuskopiointi ajastettu onnistuneesti", + "board-cleanup-failed": "Taulun siivous epäonnistui", + "board-cleanup-scheduled": "Taulun siivous ajastettu onnistuneesti", + "board-operations": "Taulun toiminnot", + "cron-jobs": "Ajastetut työt", + "cron-migrations": "Ajastetut siirrot", + "cron-job-delete-confirm": "Haluatko varmasti poistaa tämän ajastetun työn?", + "cron-job-delete-failed": "Ajastetun työn poistaminen epäonnistui", + "cron-job-deleted": "Ajastettu työ poistettu onnistuneesti", + "cron-job-pause-failed": "Ajastetun työn keskeyttäminen epäonnistui", + "cron-job-paused": "Ajastettu työ keskeytetty onnistuneesti", + "filesystem-path-description": "Peruspolku tiedostojen tallennukseen", + "gridfs-enabled": "GridFS käytössä", + "gridfs-enabled-description": "Käytä MongoDB GridFS:ää tiedostojen tallennukseen", + "migration-pause-failed": "Siirtojen keskeyttäminen epäonnistui", + "migration-paused": "Siirrot keskeytetty onnistuneesti", + "migration-progress": "Siirtojen edistyminen", + "migration-start-failed": "Siirtojen aloittaminen epäonnistui", + "migration-started": "Siirrot aloitettu onnistuneesti", + "migration-status": "Siirron tila", + "migration-stop-confirm": "Haluatko varmasti pysäyttää kaikki siirrot?", + "migration-stop-failed": "Siirtojen pysäyttäminen epäonnistui", + "migration-stopped": "Siirrot pysäytetty onnistuneesti", + "mongodb-gridfs-storage": "MongoDB GridFS tallennus", + "pause-all-migrations": "Keskeytä kaikki siirrot", + "s3-access-key": "S3 käyttöavain", + "s3-access-key-description": "AWS S3 käyttöavain tunnistautumiseen", + "s3-access-key-placeholder": "Syötä S3 käyttöavain", + "s3-bucket": "S3 kauha", + "s3-bucket-description": "S3 kauhan nimi tiedostojen tallennukseen", + "s3-connection-failed": "S3 yhteys epäonnistui", + "s3-connection-success": "S3 yhteys onnistui", + "s3-enabled": "S3 käytössä", + "s3-enabled-description": "Käytä AWS S3:ää tai MinIO:ta tiedostojen tallennukseen", + "s3-endpoint": "S3 päätepiste", + "s3-endpoint-description": "S3 päätepisteen URL (esim. s3.amazonaws.com tai minio.example.com)", + "s3-minio-storage": "S3/MinIO tallennus", + "s3-port": "S3 portti", + "s3-port-description": "S3 päätepisteen porttinumero", + "s3-region": "S3 alue", + "s3-region-description": "AWS S3 alue (esim. us-east-1)", + "s3-secret-key": "S3 salainen avain", + "s3-secret-key-description": "AWS S3 salainen avain tunnistautumiseen", + "s3-secret-key-placeholder": "Syötä S3 salainen avain", + "s3-secret-key-required": "S3 salainen avain vaaditaan", + "s3-settings-save-failed": "S3 asetusten tallentaminen epäonnistui", + "s3-settings-saved": "S3 asetukset tallennettu onnistuneesti", + "s3-ssl-enabled": "S3 SSL käytössä", + "s3-ssl-enabled-description": "Käytä SSL/TLS:ää S3 yhteyksille", + "save-s3-settings": "Tallenna S3 asetukset", + "schedule-board-archive": "Aikatauluta taulun arkistointi", + "schedule-board-backup": "Aikatauluta taulun varmuuskopiointi", + "schedule-board-cleanup": "Aikatauluta taulun siivous", + "scheduled-board-operations": "Aikataulutetut taulun toiminnot", + "start-all-migrations": "Aloita kaikki siirrot", + "stop-all-migrations": "Pysäytä kaikki siirrot", + "test-s3-connection": "Testaa S3 yhteys", + "writable-path": "Kirjoitettava polku", + "writable-path-description": "Perushakemistopolku tiedostojen tallennukseen", + "add-job": "Lisää työ", + "attachment-migration": "Liitteiden siirto", + "attachment-monitoring": "Liitteiden seuranta", + "attachment-settings": "Liitteiden asetukset", + "attachment-storage-settings": "Tallennusasetukset", + "automatic-migration": "Automaattinen siirto", + "back-to-settings": "Takaisin asetuksiin", + "board-id": "Taulun tunnus", + "board-migration": "Taulun siirto", + "board-migrations": "Taulu migraatiot", + "card-show-lists-on-minicard": "Näytä listat minikortilla", + "comprehensive-board-migration": "Perusteellinen taulu migraatio", + "comprehensive-board-migration-description": "Suorittaa kattavia tarkistuksia ja korjauksia taulun tietojen eheyden varmistamiseksi, mukaan lukien listajärjestyksen, korttien sijainnit ja uimaratarakenteen.", + "delete-duplicate-empty-lists-migration": "Poista kaksoiskappaleet tyhjistä listoista", + "delete-duplicate-empty-lists-migration-description": "Poistaa tyhjät kaksoiskappalelistat turvallisesti. Poistaa vain listat, joissa ei ole kortteja JA joilla on toinen samanniminen lista, joka sisältää kortteja.", + "lost-cards": "Kadonneet kortit", + "lost-cards-list": "Palautetut kohteet", + "restore-lost-cards-migration": "Palauta kadonneet kortit", + "restore-lost-cards-migration-description": "Etsii ja palauttaa kortit ja listat, joista puuttuu swimlaneId tai listId. Luo 'Kadonneet kortit' -uimaradan, jotta kaikki kadonneet ovat taas näkyvissä.", + "restore-all-archived-migration": "Palauta kaikki arkistoidut", + "restore-all-archived-migration-description": "Palauttaa kaikki arkistoidut uimaradat, listat ja kortit. Korjaa automaattisesti puuttuvat uimaratatunnukset tai listatunnukset, jotta kohteet ovat näkyvissä.", + "fix-missing-lists-migration": "Korjaa puuttuvat listat", + "fix-missing-lists-migration-description": "Havaitsee ja korjaa puuttuvat tai vioittuneet listat taulun rakenteessa.", + "fix-avatar-urls-migration": "Korjaa avatar-URL-osoitteet", + "fix-avatar-urls-migration-description": "Päivittää taulun jäsenten avatar-osoitteiden URL-osoitteet oikean tallennustilan käyttämiseksi ja korjaa rikkinäiset avatar-viittaukset.", + "fix-all-file-urls-migration": "Korjaa kaikki tiedostojen URL-osoitteet", + "fix-all-file-urls-migration-description": "Päivittää kaikkien tällä taululla olevien tiedostoliitteiden URL-osoitteet käyttämään oikeaa tallennuspalvelinta ja korjaa rikkinäiset tiedostoviittaukset.", + "migration-needed": "Migraatio tarvitaan", + "migration-complete": "Valmis", + "migration-running": "Suoritetaan...", + "migration-successful": "Migraatio valmistui onnistuneesti", + "migration-failed": "Migraatio epäonnistui", + "migrations": "Migraatiot", + "migrations-admin-only": "Vain taulu ylläpitäjät voivat suorittaa migraatioita", + "migrations-description": "Suorita tietojen eheystarkistukset ja korjaukset tälle taululle. Jokainen migraatio voidaan suorittaa erikseen.", + "no-issues-found": "Ei löytynyt ongelmia", + "run-migration": "Suorita migraatio", + "run-comprehensive-migration-confirm": "Tämä suorittaa kattavan migraation, jolla tarkistetaan ja korjataan taulun tietojen eheys. Tämä voi kestää hetken. Jatketaanko?", + "run-delete-duplicate-empty-lists-migration-confirm": "Tämä muuntaa ensin kaikki jaetut listat uimaratakohtaisiksi listoiksi ja poistaa sitten tyhjät listat, joissa on samanniminen kaksoiskappale, joka sisältää kortteja. Vain todella tarpeettomat tyhjät listat poistetaan. Jatketaanko?", + "run-restore-lost-cards-migration-confirm": "Tämä luo Kadonneet kortit -uimaradan ja palauttaa kaikki kortit ja listat, joista puuttuu uimaradan tunnus tai listan tunnus. Tämä vaikuttaa vain arkistoimattomiin kohteisiin. Jatketaanko?", + "run-restore-all-archived-migration-confirm": "Tämä palauttaa KAIKKI arkistoidut uintikaistat, listat ja kortit, jolloin ne näkyvät taas. Puuttuvista tunnuksista puuttuvat kohteet korjataan automaattisesti. Tätä ei voi helposti perua. Jatketaanko?", + "run-fix-missing-lists-migration-confirm": "Tämä havaitsee ja korjaa puuttuvat tai vioittuneet listat taulun rakenteessa. Jatketaanko?", + "run-fix-avatar-urls-migration-confirm": "Tämä päivittää taulun jäsenten avatar-URL-osoitteet käyttämään oikeaa tallennustilaa. Jatketaanko?", + "run-fix-all-file-urls-migration-confirm": "Tämä päivittää kaikkien tällä taululla olevien tiedostoliitteiden URL-osoitteet käyttämään oikeaa tallennuspalvelinta. Jatketaanko?", + "restore-lost-cards-nothing-to-restore": "Ei kadonneita uintikaistoja, listoja tai kortteja palautettavaksi", + + "migration-progress-title": "Taulu migraatio meneillään", + "migration-progress-overall": "Kokonaisedistyminen", + "migration-progress-current-step": "Nykyinen vaihe", + "migration-progress-status": "Tilanne", + "migration-progress-details": "Yksityiskohdat", + "migration-progress-note": "Odota hetki, siirrämme taulusi uusimpaan rakenteeseen...", + + "step-analyze-board-structure": "Analysoi taulun rakennetta", + "step-fix-orphaned-cards": "Korjaa orvot kortit", + "step-convert-shared-lists": "Muunna jaetut listat", + "step-ensure-per-swimlane-lists": "Varmista uimaratakohtaiset listat", + "step-validate-migration": "Varmistetaan migraatio", + "step-fix-avatar-urls": "Korjaa avatar-URL-osoitteet", + "step-fix-attachment-urls": "Korjaa liitetiedosto URLit", + "step-analyze-lists": "Analysoidaan listoja", + "step-create-missing-lists": "Luo puuttuvat listat", + "step-update-cards": "Päivitä kortit", + "step-finalize": "Viimeistellään", + "step-delete-duplicate-empty-lists": "Poista kaksoiskappaleet tyhjistä listoista", + "step-ensure-lost-cards-swimlane": "Varmistetaan hävinneiden korttien uimarata", + "step-restore-lists": "Palauta listat", + "step-restore-cards": "Palauta kortit", + "step-restore-swimlanes": "Palauta uimaradat", + "step-fix-missing-ids": "Korjaa puuttuvat ID:t", + "step-scan-users": "Tarkistetaan taulun jäsenten avatarit", + "step-scan-files": "Tarkistetaan taulun liitetiedostot", + "step-fix-file-urls": "Korjataan tiedosto URLit", + "cleanup": "Siivous", + "cleanup-old-jobs": "Siivoa vanhat työt", + "completed": "Valmistunut", + "conversion-info-text": "Tämä muunnos suoritetaan kerran per taulu ja parantaa suorituskykyä. Voit jatkaa taulun käyttöä normaalisti.", + "converting-board": "Muunnetaan taulua", + "converting-board-description": "Muunnetaan taulun rakennetta parantamaan toiminnallisuutta. Tämä voi kestää hetken.", + "cpu-cores": "Suorittimen ytimet", + "cpu-usage": "Suorittimen käyttö", + "current-action": "Nykyinen toiminto", + "database-migration": "Tietokannan siirto", + "database-migration-description": "Päivitetään tietokannan rakennetta parantamaan toiminnallisuutta ja suorituskykyä. Tämä prosessi voi kestää useita minuutteja.", + "database-migrations": "Tietokannan siirrot", + "days-old": "Päivää vanha", + "duration": "Kesto", + "errors": "Virheet", + "estimated-time-remaining": "Arvioitu jäljellä oleva aika", + "every-1-day": "Kerran päivässä", + "every-1-hour": "Kerran tunnissa", + "every-1-minute": "Kerran minuutissa", + "every-10-minutes": "10 minuutin välein", + "every-30-minutes": "30 minuutin välein", + "every-5-minutes": "5 minuutin välein", + "every-6-hours": "6 tunnin välein", + "export-monitoring": "Vie seuranta", + "filesystem-attachments": "Tiedostojärjestelmän liitteet", + "filesystem-size": "Tiedostojärjestelmän koko", + "filesystem-storage": "Tiedostojärjestelmä", + "force-board-scan": "Pakota taulun skannaus", + "gridfs-attachments": "GridFS-liitteet", + "gridfs-size": "GridFS-koko", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Piilota lista minikortilta", + "idle-migration": "Tyhjäkäynti-siirto", + "job-description": "Työn kuvaus", + "job-details": "Työn yksityiskohdat", + "job-name": "Työn nimi", + "job-queue": "Työjono", + "last-run": "Viimeksi ajettu", + "max-concurrent": "Maksimi samanaikainen", + "memory-usage": "Muistin käyttö", + "migrate-all-to-filesystem": "Siirrä kaikki tiedostojärjestelmään", + "migrate-all-to-gridfs": "Siirrä kaikki GridFS:ään", + "migrate-all-to-s3": "Siirrä kaikki S3:een", + "migrated-attachments": "Siirretyt liitteet", + "migration-batch-size": "Erän koko", + "migration-batch-size-description": "Liitteiden määrä käsiteltäväksi kussakin erässä (1-100)", + "migration-cpu-threshold": "Suorittimen kynnys (%)", + "migration-cpu-threshold-description": "Keskeytä siirto kun suorittimen käyttö ylittää tämän prosenttiosuuden (10-90)", + "migration-delay-ms": "Viive (ms)", + "migration-delay-ms-description": "Viive erien välillä millisekunteina (100-10000)", + "migration-detector": "Siirron tunnistin", + "migration-info-text": "Tietokannan siirrot suoritetaan kerran ja parantavat järjestelmän suorituskykyä. Prosessi jatkuu taustalla vaikka suljet selaimen.", + "migration-log": "Siirron loki", + "migration-markers": "Siirron merkit", + "migration-resume-failed": "Siirron jatkaminen epäonnistui", + "migration-resumed": "Siirto jatkettu", + "migration-steps": "Siirron vaiheet", + "migration-warning-text": "Älä sulje selainta siirron aikana. Prosessi jatkuu taustalla mutta voi kestää kauemmin valmistuakseen.", + "monitoring-export-failed": "Seurannan vienti epäonnistui", + "monitoring-refresh-failed": "Seurannan päivittäminen epäonnistui", + "next": "Seuraava", + "next-run": "Seuraava ajo", + "of": " / ", + "operation-type": "Toiminnon tyyppi", + "overall-progress": "Kokonaisedistyminen", + "page": "Sivu", + "pause-migration": "Keskeytä siirto", + "previous": "Edellinen", + "refresh": "Päivitä", + "refresh-monitoring": "Päivitä seuranta", + "remaining-attachments": "Jäljellä olevat liitteet", + "resume-migration": "Jatka siirtoa", + "run-once": "Aja kerran", + "s3-attachments": "S3-liitteet", + "s3-size": "S3-koko", + "s3-storage": "S3", + "scanning-status": "Skannauksen tila", + "schedule": "Aikataulu", + "search-boards-or-operations": "Etsi tauluja tai toimintoja...", + "show-list-on-minicard": "Näytä lista minikortilla", + "showing": "Näytetään", + "start-test-operation": "Aloita testitoiminto", + "start-time": "Aloitusaika", + "step-progress": "Vaiheen edistyminen", + "stop-migration": "Pysäytä siirto", + "storage-distribution": "Tallennuksen jakautuminen", + "system-resources": "Järjestelmän resurssit", + "total-attachments": "Liitteitä yhteensä", + "total-operations": "Toimintoja yhteensä", + "total-size": "Koko yhteensä", + "unmigrated-boards": "Siirtämättömät taulut", + "weight": "Paino", + "idle": "Tyhjäkäynti", + "complete": "Valmis", + "cron": "Ajastus" } diff --git a/imports/i18n/data/fr-CH.i18n.json b/imports/i18n/data/fr-CH.i18n.json index 73b5f2995..5fa3fa719 100644 --- a/imports/i18n/data/fr-CH.i18n.json +++ b/imports/i18n/data/fr-CH.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/fr-FR.i18n.json b/imports/i18n/data/fr-FR.i18n.json index f7142931a..54b4536c1 100644 --- a/imports/i18n/data/fr-FR.i18n.json +++ b/imports/i18n/data/fr-FR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "commentaire supprimé %s", "activity-receivedDate": "date de réception éditée de %s à %s", "activity-startDate": "date de début éditée de %s à %s", + "allboards.starred": "Starred", + "allboards.templates": "Modèles", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "date d'échéance éditée de %s à %s", "activity-endDate": "date de fin éditée de %s à %s", "add-attachment": "Ajouter une pièce jointe", @@ -190,7 +202,9 @@ "board-view-collapse": "Réduire", "board-view-gantt": "Gantt", "board-view-lists": "Listes", - "bucket-example": "Comme « todo list » par exemple", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Annuler", "card-archived": "Cette carte est archivée", "board-archived": "Ce tableau est archivé", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Titre de la première carte\", \"description\":\"Description de la première carte\"}, {\"title\":\"Titre de la seconde carte\",\"description\":\"Description de la seconde carte\"},{\"title\":\"Titre de la dernière carte\",\"description\":\"Description de la dernière carte\"} ]", "create": "Créer", "createBoardPopup-title": "Créer un tableau", + "createTemplateContainerPopup-title": "Ajouter un conteneur de modèles", "chooseBoardSourcePopup-title": "Importer un tableau", "createLabelPopup-title": "Créer une étiquette", "createCustomField": "Créer un champ personnalisé", @@ -354,6 +369,10 @@ "custom-field-text": "Texte", "custom-fields": "Champs personnalisés", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Refuser", "default-avatar": "Avatar par défaut", "delete": "Supprimer", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Modifier la notification", "editProfilePopup-title": "Modifier le profil", "email": "E-mail", + "email-address": "Email Address", "email-enrollAccount-subject": "Un compte a été créé pour vous sur __siteName__", "email-enrollAccount-text": "Bonjour __user__,\n\nPour commencer à utiliser ce service, il suffit de cliquer sur le lien ci-dessous.\n\n__url__\n\nMerci.", "email-fail": "Échec de l'envoi du courriel.", @@ -748,6 +768,8 @@ "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. Cela est irréversible.", "boardDeletePopup-title": "Supprimer le tableau ?", "delete-board": "Supprimer le tableau", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Sous-tâches du tableau __board__", "default": "Défaut", "defaultdefault": "Défaut", @@ -755,7 +777,7 @@ "subtask-settings": "Paramètres des sous-tâches", "card-settings": "Paramètres de la carte", "minicard-settings": "Paramètres de la minicarte", - "boardSubtaskSettingsPopup-title": "Paramètres des sous-tâches du tableau", + "boardSubtaskSettingsPopup-title": "Paramètres des sous-tâches", "boardCardSettingsPopup-title": "Paramètres de la carte", "boardMinicardSettingsPopup-title": "Paramètres de la minicarte", "deposit-subtasks-board": "Déposer des sous-tâches dans ce tableau :", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Moi", "dueCardsViewChange-choice-all": "Tous les utilisateurs", "dueCardsViewChange-choice-all-description": "Visualise toutes les cartes incomplètes avec une date *échue* pour lesquelles l'utilisateur possède les droits", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Cartes en erreur", "board-title-not-found": "Tableau '%s' non trouvé.", "swimlane-title-not-found": "Couloir '%s' non trouvé.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Statut", + "migration-progress-details": "Détails", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Terminé", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "sur", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/fr.i18n.json b/imports/i18n/data/fr.i18n.json index d0ba956f0..d7f615886 100644 --- a/imports/i18n/data/fr.i18n.json +++ b/imports/i18n/data/fr.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "commentaire supprimé %s", "activity-receivedDate": "date de réception éditée de %s à %s", "activity-startDate": "date de début éditée de %s à %s", + "allboards.starred": "Favoris", + "allboards.templates": "Modèles", + "allboards.remaining": "Restant", + "allboards.workspaces": "Espaces de travail", + "allboards.add-workspace": "Ajouter un espace de travail", + "allboards.add-workspace-prompt": "Nom de l'espace de travail", + "allboards.add-subworkspace": "Ajouter un sous-espace de travail", + "allboards.add-subworkspace-prompt": "Nom du sous-espace de travail", + "allboards.edit-workspace": "Modifier l'espace de travail", + "allboards.edit-workspace-name": "Nom de l'espace de travail", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Cliquez sur les cases à cocher pour sélectionner les tableaux", "activity-dueDate": "date d'échéance éditée de %s à %s", "activity-endDate": "date de fin éditée de %s à %s", "add-attachment": "Ajouter une pièce jointe", @@ -190,7 +202,9 @@ "board-view-collapse": "Réduire", "board-view-gantt": "Gantt", "board-view-lists": "Listes", - "bucket-example": "Comme « todo list » par exemple", + "bucket-example": "Comme « Liste d'envies » par exemple", + "calendar-previous-month-label": "Mois précédent", + "calendar-next-month-label": "Mois suivant", "cancel": "Annuler", "card-archived": "Cette carte est archivée", "board-archived": "Ce tableau est archivé", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Titre de la première carte\", \"description\":\"Description de la première carte\"}, {\"title\":\"Titre de la seconde carte\",\"description\":\"Description de la seconde carte\"},{\"title\":\"Titre de la dernière carte\",\"description\":\"Description de la dernière carte\"} ]", "create": "Créer", "createBoardPopup-title": "Créer un tableau", + "createTemplateContainerPopup-title": "Ajouter un conteneur de modèles", "chooseBoardSourcePopup-title": "Importer un tableau", "createLabelPopup-title": "Créer une étiquette", "createCustomField": "Créer un champ personnalisé", @@ -354,6 +369,10 @@ "custom-field-text": "Texte", "custom-fields": "Champs personnalisés", "date": "Date", + "date-format": "Format de la date", + "date-format-yyyy-mm-dd": "AAAA-MM-JJ", + "date-format-dd-mm-yyyy": "JJ-MM-AAAA", + "date-format-mm-dd-yyyy": "MM-JJ-AAAA", "decline": "Refuser", "default-avatar": "Avatar par défaut", "delete": "Supprimer", @@ -378,20 +397,21 @@ "editLabelPopup-title": "Modifier l'étiquette", "editNotificationPopup-title": "Modifier la notification", "editProfilePopup-title": "Modifier le profil", - "email": "E-mail", + "email": "Courriel", + "email-address": "Adresse de courriel", "email-enrollAccount-subject": "Un compte a été créé pour vous sur __siteName__", "email-enrollAccount-text": "Bonjour __user__,\n\nPour commencer à utiliser ce service, il suffit de cliquer sur le lien ci-dessous.\n\n__url__\n\nMerci.", "email-fail": "Échec de l'envoi du courriel.", - "email-fail-text": "Une erreur est survenue en tentant d'envoyer l'email", - "email-invalid": "Adresse e-mail incorrecte.", - "email-invite": "Inviter par e-mail", + "email-fail-text": "Une erreur est survenue en tentant d'envoyer le courriel", + "email-invalid": "Adresse de courriel incorrecte.", + "email-invite": "Inviter par courriel", "email-invite-subject": "__inviter__ vous a envoyé une invitation", "email-invite-text": "Cher/Chère __user__,\n\n__inviter__ vous invite à rejoindre le tableau \"__board__\" pour collaborer.\n\nVeuillez suivre le lien ci-dessous :\n\n__url__\n\nMerci.", "email-resetPassword-subject": "Réinitialiser votre mot de passe sur __siteName__", "email-resetPassword-text": "Bonjour __user__,\n\nPour réinitialiser votre mot de passe, cliquez sur le lien ci-dessous.\n\n__url__\n\nMerci.", "email-sent": "Courriel envoyé", "email-verifyEmail-subject": "Vérifier votre adresse de courriel sur __siteName__", - "email-verifyEmail-text": "Bonjour __user__,\n\nPour vérifier votre compte courriel, il suffit de cliquer sur le lien ci-dessous.\n\n__url__\n\nMerci.", + "email-verifyEmail-text": "Bonjour __user__,\n\nPour vérifier le courriel de votre compte, il suffit de cliquer sur le lien ci-dessous.\n\n__url__\n\nMerci.", "enable-vertical-scrollbars": "Activer les barres de défilement verticales", "enable-wip-limit": "Activer la limite WIP", "error-board-doesNotExist": "Ce tableau n'existe pas", @@ -407,7 +427,7 @@ "error-username-taken": "Ce nom d'utilisateur est déjà utilisé", "error-orgname-taken": "Ce nom d'organisation est déjà utilisé", "error-teamname-taken": "Ce nom d'équipe est déjà utilisé", - "error-email-taken": "Cette adresse mail est déjà utilisée", + "error-email-taken": "Cette adresse de courriel est déjà utilisée", "export-board": "Exporter le tableau", "export-board-json": "Exporter le tableau en JSON", "export-board-csv": "Exporter le tableau en CSV", @@ -631,9 +651,9 @@ "upload": "Télécharger", "upload-avatar": "Télécharger un avatar", "uploaded-avatar": "Avatar téléchargé", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "Chargement des fichiers", + "upload-failed": "Le chargement a échoué", + "upload-completed": "Le chargement est terminé", "custom-top-left-corner-logo-image-url": "URL de l'Image du logo personnalisé dans le coin supérieur gauche", "custom-top-left-corner-logo-link-url": "Lien URL du logo personnalisé dans le coin supérieur gauche", "custom-top-left-corner-logo-height": "Hauteur du logo personnalisé dans le coin supérieur gauche. Défaut : 27", @@ -669,9 +689,9 @@ "invite": "Inviter", "invite-people": "Inviter une personne", "to-boards": "Au(x) tableau(x)", - "email-addresses": "Adresses mail", - "smtp-host-description": "L'adresse du serveur SMTP qui gère vos mails.", - "smtp-port-description": "Le port des mails sortants du serveur SMTP.", + "email-addresses": "Adresses de courriel", + "smtp-host-description": "L'adresse du serveur SMTP qui gère vos courriels.", + "smtp-port-description": "Le port du serveur SMTP utilisé pour les courriels sortants.", "smtp-tls-description": "Activer la gestion de TLS sur le serveur SMTP", "smtp-host": "Hôte SMTP", "smtp-port": "Port SMTP", @@ -679,12 +699,12 @@ "smtp-password": "Mot de passe", "smtp-tls": "Prise en charge de TLS", "send-from": "De", - "send-smtp-test": "Envoyer un mail de test à vous-même", + "send-smtp-test": "Envoyer un courriel de test à vous-même", "invitation-code": "Code d'invitation", "email-invite-register-subject": "__inviter__ vous a envoyé une invitation", "email-invite-register-text": "Cher/Chère __user__,\n\n__inviter__ vous invite à le rejoindre sur le tableau kanban pour collaborer.\n\nVeuillez suivre le lien ci-dessous :\n__url__\n\nVotre code d'invitation est : __icode__\n\nMerci.", - "email-smtp-test-subject": "E-mail de test SMTP", - "email-smtp-test-text": "Vous avez envoyé un mail avec succès", + "email-smtp-test-subject": "Courriel de test SMTP", + "email-smtp-test-text": "Vous avez envoyé un courriel avec succès", "error-invitation-code-not-exist": "Ce code d'invitation n'existe pas.", "error-notAuthorized": "Vous n'êtes pas autorisé à accéder à cette page.", "webhook-title": "Nom du webhook", @@ -723,7 +743,7 @@ "yes": "Oui", "no": "Non", "accounts": "Comptes", - "accounts-allowEmailChange": "Autoriser le changement d'adresse mail", + "accounts-allowEmailChange": "Autoriser le changement d'adresse de courriel", "accounts-allowUserNameChange": "Autoriser le changement d'identifiant", "tableVisibilityMode-allowPrivateOnly": "Visibilité des tableaux: N'autoriser que des tableaux privés", "tableVisibilityMode" : "Visibilité des tableaux", @@ -748,6 +768,8 @@ "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. Cela est irréversible.", "boardDeletePopup-title": "Supprimer le tableau ?", "delete-board": "Supprimer le tableau", + "delete-duplicate-lists": "Supprimer les listes en doublon ? ", + "delete-duplicate-lists-confirm": "Êtes-vous sûr ? Cela supprimera toutes les listes en doublon qui ont le même nom et qui ne contiennent aucune carte.", "default-subtasks-board": "Sous-tâches du tableau __board__", "default": "Défaut", "defaultdefault": "Défaut", @@ -755,7 +777,7 @@ "subtask-settings": "Paramètres des sous-tâches", "card-settings": "Paramètres de la carte", "minicard-settings": "Paramètres de la mini-carte", - "boardSubtaskSettingsPopup-title": "Paramètres des sous-tâches du tableau", + "boardSubtaskSettingsPopup-title": "Paramètres des sous-tâches", "boardCardSettingsPopup-title": "Paramètres de la carte", "boardMinicardSettingsPopup-title": "Paramètres de la mini-carte", "deposit-subtasks-board": "Déposer des sous-tâches dans ce tableau :", @@ -841,7 +863,7 @@ "r-uncheck": "Décocher", "r-item": "élément", "r-of-checklist": "de la check-list", - "r-send-email": "Envoyer un email", + "r-send-email": "Envoyer un courriel", "r-to": "à", "r-of": "sur", "r-subject": "sujet", @@ -850,7 +872,7 @@ "r-d-move-to-top-spec": "Déplacer la carte en haut de la liste", "r-d-move-to-bottom-gen": "Déplacer la carte en bas de sa liste", "r-d-move-to-bottom-spec": "Déplacer la carte en bas de la liste", - "r-d-send-email": "Envoyer un email", + "r-d-send-email": "Envoyer le courriel", "r-d-send-email-to": "à", "r-d-send-email-subject": "sujet", "r-d-send-email-message": "message", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Moi", "dueCardsViewChange-choice-all": "Tous les utilisateurs", "dueCardsViewChange-choice-all-description": "Visualise toutes les cartes incomplètes avec une date *échue* pour lesquelles l'utilisateur possède les droits", + "dueCards-noResults-title": "Aucune carte avec échéance trouvée", + "dueCards-noResults-description": "Vous n'avez aucune carte avec échéance en ce moment.", "broken-cards": "Cartes en erreur", "board-title-not-found": "Tableau '%s' non trouvé.", "swimlane-title-not-found": "Couloir '%s' non trouvé.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "L'utilisateur est activé - Cliquer pour le désactiver", "admin-people-user-inactive": "L'utilisateur est désactivé - Cliquer pour l'activer", "accounts-lockout-all-users-unlocked": "Tous les utilisateurs bloqués ont été déverrouillés", - "accounts-lockout-unlock-all": "Tout déverrouiller" + "accounts-lockout-unlock-all": "Tout déverrouiller", + "active-cron-jobs": "Travaux actifs planifiés", + "add-cron-job": "Ajouter un travail planifié", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Travaux planifiés", + "cron-migrations": "Migrations planifiées", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Migration automatique", + "back-to-settings": "Retour aux paramètres", + "board-id": "ID du tableau", + "board-migration": "Migration du tableau", + "board-migrations": "Migrations de tableau", + "card-show-lists-on-minicard": "Afficher les listes sur la mini-carte", + "comprehensive-board-migration": "Migration complète de tableau", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Supprimer les listes vides en doublon ? ", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Cartes perdues", + "lost-cards-list": "Éléments restaurés", + "restore-lost-cards-migration": "Restaurer les cartes perdues", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Corriger les URLs d'avatar", + "fix-avatar-urls-migration-description": "Mets à jour les URLs d'avatar des participants du tableau pour utiliser le bon gestionnaire de stockage et corriger les références défaillantes d'avatar ", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration requise", + "migration-complete": "Terminé", + "migration-running": "En cours ...", + "migration-successful": "Migration terminée avec succès", + "migration-failed": "Migration en échec", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "Aucun problème détecté", + "run-migration": "Lancer la migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Migration du tableau en cours", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Étape courante", + "migration-progress-status": "Statut", + "migration-progress-details": "Détails", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Corriger les cartes orphelines", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Valider la migration", + "step-fix-avatar-urls": "Corriger les URLs d'avatar", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Supprimer les listes vides en doublon ? ", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restaurer les cartes", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Terminé", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "Cœurs du CPU ", + "cpu-usage": "Utilisation du CPU", + "current-action": "Current Action", + "database-migration": "Migration base de données", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Migrations base de données", + "days-old": "Jours d'ancienneté", + "duration": "Durée", + "errors": "Erreurs", + "estimated-time-remaining": "Temps restant estimé", + "every-1-day": "Tous les jours", + "every-1-hour": "Toutes les heures", + "every-1-minute": "Toutes les minutes", + "every-10-minutes": "Toutes les 10 minutes", + "every-30-minutes": "Toutes les 30 minutes", + "every-5-minutes": "Toutes les 5 minutes", + "every-6-hours": "Toutes les 6 heures", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Masquer la liste sur la mini-carte", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Dernière exécution", + "max-concurrent": "Max Concurrent", + "memory-usage": "Utilisation de la mémoire", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "Seuil CPU (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Suivant", + "next-run": "Prochaine exécution", + "of": "sur", + "operation-type": "Type d'opération", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Précédent", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Exécuter une fois", + "s3-attachments": "Pièces jointes S3", + "s3-size": "Taille S3", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Afficher la liste sur la mini-carte", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Taille totale", + "unmigrated-boards": "Tableaux non migrés", + "weight": "Poids", + "idle": "Inactif", + "complete": "Terminé", + "cron": "Planification" } diff --git a/imports/i18n/data/fy-NL.i18n.json b/imports/i18n/data/fy-NL.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/fy-NL.i18n.json +++ b/imports/i18n/data/fy-NL.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/fy.i18n.json b/imports/i18n/data/fy.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/fy.i18n.json +++ b/imports/i18n/data/fy.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/gl-ES.i18n.json b/imports/i18n/data/gl-ES.i18n.json index fde6502a6..ab6c97129 100644 --- a/imports/i18n/data/gl-ES.i18n.json +++ b/imports/i18n/data/gl-ES.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Engadir anexo", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Listas", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancelar", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Crear", "createBoardPopup-title": "Crear taboleiro", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importar taboleiro", "createLabelPopup-title": "Crear etiqueta", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Data", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Rexeitar", "default-avatar": "Avatar predeterminado", "delete": "Eliminar", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editar a notificación", "editProfilePopup-title": "Editar o perfil", "email": "Correo electrónico", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/gl.i18n.json b/imports/i18n/data/gl.i18n.json index 0d5d6d51f..088d60d69 100644 --- a/imports/i18n/data/gl.i18n.json +++ b/imports/i18n/data/gl.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Engadir anexo", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Listas", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancelar", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Crear", "createBoardPopup-title": "Crear taboleiro", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importar taboleiro", "createLabelPopup-title": "Crear etiqueta", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Data", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Rexeitar", "default-avatar": "Avatar predeterminado", "delete": "Eliminar", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editar a notificación", "editProfilePopup-title": "Editar o perfil", "email": "Correo electrónico", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/gu-IN.i18n.json b/imports/i18n/data/gu-IN.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/gu-IN.i18n.json +++ b/imports/i18n/data/gu-IN.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/he-IL.i18n.json b/imports/i18n/data/he-IL.i18n.json index 00a3b220d..0484f7b10 100644 --- a/imports/i18n/data/he-IL.i18n.json +++ b/imports/i18n/data/he-IL.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/he.i18n.json b/imports/i18n/data/he.i18n.json index 827e98487..69afb7d25 100644 --- a/imports/i18n/data/he.i18n.json +++ b/imports/i18n/data/he.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "התגובה %s נמחקה", "activity-receivedDate": "תאריך הקבלה השתנה מ־%s ל־%s", "activity-startDate": "תאריך ההתחלה השתנה מ־%s ל־%s", + "allboards.starred": "סומן בכוכב", + "allboards.templates": "תבניות", + "allboards.remaining": "נותרו", + "allboards.workspaces": "מרחבי עבודה", + "allboards.add-workspace": "הוספת מרחב עבודה", + "allboards.add-workspace-prompt": "שם מרחב עבודה", + "allboards.add-subworkspace": "הוספת תת־מרחב עבודה", + "allboards.add-subworkspace-prompt": "שם תת־מרחב עבודה", + "allboards.edit-workspace": "עריכת מרחב עבודה", + "allboards.edit-workspace-name": "שם מרחב עבודה", + "allboards.edit-workspace-icon": "סמל מרחב עבודה (markdown)", + "multi-selection-active": "יש לסמן את התיבות כדי לבחור לוחות", "activity-dueDate": "תאריך היעד השתנה מ־%s ל־%s", "activity-endDate": "תאריך הסיום השתנה מ־%s ל־%s", "add-attachment": "הוספת קובץ מצורף", @@ -190,7 +202,9 @@ "board-view-collapse": "צמצום", "board-view-gantt": "גאנט", "board-view-lists": "רשימות", - "bucket-example": "כמו למשל „רשימת המשימות“", + "bucket-example": "כמו „רשימת משאלות” למשל", + "calendar-previous-month-label": "החודש הקודם", + "calendar-next-month-label": "החודש הבא", "cancel": "ביטול", "card-archived": "כרטיס זה שמור בארכיון.", "board-archived": "הלוח עבר לארכיון", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"כותרת כרטיס ראשון\", \"description\":\"תיאור כרטיס ראשון\"}, {\"title\":\"כותרת כרטיס שני\",\"description\":\"תיאור כרטיס שני\"},{\"title\":\"כותרת כרטיס אחרון\",\"description\":\"תיאור כרטיס אחרון\"} ]", "create": "יצירה", "createBoardPopup-title": "יצירת לוח", + "createTemplateContainerPopup-title": "הוספת מכולה לתבנית", "chooseBoardSourcePopup-title": "ייבוא לוח", "createLabelPopup-title": "יצירת תווית", "createCustomField": "יצירת שדה", @@ -354,6 +369,10 @@ "custom-field-text": "טקסט", "custom-fields": "שדות מותאמים אישית", "date": "תאריך", + "date-format": "תבנית תאריך", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "סירוב", "default-avatar": "תמונת משתמש כבררת מחדל", "delete": "מחיקה", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "שינוי דיווח", "editProfilePopup-title": "עריכת פרופיל", "email": "דוא״ל", + "email-address": "כתובת דוא״ל", "email-enrollAccount-subject": "נוצר עבורך חשבון באתר __siteName__", "email-enrollAccount-text": "__user__ שלום,\n\nכדי להתחיל להשתמש בשירות, יש ללחוץ על הקישור המופיע להלן.\n\n__url__\n\nתודה.", "email-fail": "שליחת ההודעה בדוא״ל נכשלה", @@ -631,9 +651,9 @@ "upload": "העלאה", "upload-avatar": "העלאת תמונת משתמש", "uploaded-avatar": "הועלתה תמונה משתמש", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "העלאת קבצים", + "upload-failed": "ההעלאה נכשלה", + "upload-completed": "ההעלאה הושלמה", "custom-top-left-corner-logo-image-url": "כתובת תמונת לוגו משלך לפינה הימנית העליונה", "custom-top-left-corner-logo-link-url": "כתובת קישור לוגו משלך לפינה הימנית העליונה", "custom-top-left-corner-logo-height": "גובה לוגו מותאם אישית בפינה הימנית העליונה. בררת מחדל: 27", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "כל הרשימות, הכרטיסים, התווית והפעולות יימחקו ולא תהיה לך דרך לשחזר את תכני הלוח. אין אפשרות לבטל.", "boardDeletePopup-title": "למחוק את הלוח?", "delete-board": "מחיקת לוח", + "delete-duplicate-lists": "מחיקת רשימות כפולות", + "delete-duplicate-lists-confirm": "להמשיך? הפעולה הזאת תמחק את כל הרשימות הכפולות שיש להן את אותו השם ואינן מכילות כרטיסים.", "default-subtasks-board": "תת־משימות עבור הלוח __board__", "default": "בררת מחדל", "defaultdefault": "בררת מחדל", @@ -755,7 +777,7 @@ "subtask-settings": "הגדרות תתי משימות", "card-settings": "הגדרות כרטיס", "minicard-settings": "הגדרות כרטיסון", - "boardSubtaskSettingsPopup-title": "הגדרות תת־משימות בלוח", + "boardSubtaskSettingsPopup-title": "הגדרות תתי משימות", "boardCardSettingsPopup-title": "הגדרות כרטיס", "boardMinicardSettingsPopup-title": "הגדרות כרטיסון", "deposit-subtasks-board": "הפקדת תת־משימות ללוח הזה:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "אני", "dueCardsViewChange-choice-all": "כל המשתמשים", "dueCardsViewChange-choice-all-description": "מציג את כל הכרטיסים שלא הושלמו ושיש להם *תוקף* מלוחות שלמשתמש יש הרשאה לגשת אליהם.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "כרטיסים פגומים", "board-title-not-found": "הלוח ‚%s’ לא נמצא.", "swimlane-title-not-found": "המסלול ‚%s’ לא נמצא.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "משתמש פעיל - לחיצה תשבית", "admin-people-user-inactive": "משתמש לא פעיל - לחיצה תפעיל", "accounts-lockout-all-users-unlocked": "כל המשתמשים החסומים שוחררו", - "accounts-lockout-unlock-all": "להסיר חסימה מעל כולם" + "accounts-lockout-unlock-all": "להסיר חסימה מעל כולם", + "active-cron-jobs": "משימות מתוזמנות פעילות", + "add-cron-job": "הוספת משימה מתוזמנת", + "add-cron-job-placeholder": "היכולת להוסיף משימות מתוזמנות תושק בקרוב", + "attachment-storage-configuration": "הגדרות אחסון צרופות", + "attachments-path": "נתיב צרופות", + "attachments-path-description": "הנתיב בו תאוחסנה הצרופות", + "avatars-path": "נתיב תמונות ייצוגיות", + "avatars-path-description": "הנתיב בו יישמרו קובצי התמונות הייצוגיות", + "board-archive-failed": "תזמון העברה לארכיון של הלוח נכשל", + "board-archive-scheduled": "העברת לוח לארכיון תוזמנה בהצלחה", + "board-backup-failed": "תזמון גיבוי לוח נכשל", + "board-backup-scheduled": "גיבוי הלוח תוזמן בהצלחה", + "board-cleanup-failed": "תזמון ניקוי לוח נכשל", + "board-cleanup-scheduled": "ניקוי לוח תוזמן בהצלחה", + "board-operations": "פעולות לוח", + "cron-jobs": "משימות מתוזמנות", + "cron-migrations": "הסבות מתוזמנות", + "cron-job-delete-confirm": "למחוק את המשימה המתוזמנת?", + "cron-job-delete-failed": "מחיקת המשימה המתוזמנת נכשלה", + "cron-job-deleted": "המשימה המתוזמנת נמחקה בהצלחה", + "cron-job-pause-failed": "השהיית משימה מתוזמנת נכשלה", + "cron-job-paused": "המשימה המתוזמנת הושהתה בהצלחה", + "filesystem-path-description": "נתיב בסיס לאחסון קבצים", + "gridfs-enabled": "GridFS הופעל", + "gridfs-enabled-description": "להשתמש ב־GridFS מבית MongoDB לאחסון קבצים", + "migration-pause-failed": "השהיית ההסבות נכשלה", + "migration-paused": "ההסבות הושהו בהצלחה", + "migration-progress": "התקדמות הסבה", + "migration-start-failed": "התחלת ההסבות נכשלה", + "migration-started": "ההסבות החלו בהצלחה", + "migration-status": "מצב הסבה", + "migration-stop-confirm": "לעצור את כל ההסבות?", + "migration-stop-failed": "עצירת ההסבות נכשלה", + "migration-stopped": "ההסבות נעצרו בהצלחה", + "mongodb-gridfs-storage": "אחסון GridFS מבית MongoDB", + "pause-all-migrations": "השהיית כל ההסבות", + "s3-access-key": "מפתח גישה (Access Key) ל־S3", + "s3-access-key-description": "מפתח גישה (Access Key) ל־S3 של AWS לאימות", + "s3-access-key-placeholder": "נא למלא מפתח גישה (Access Key) ל־S3", + "s3-bucket": "דלי (Bucket) ב־S3", + "s3-bucket-description": "שם דלי (Bucket) ב־S3 לאחסון", + "s3-connection-failed": "החיבור ל־S3 נכשל", + "s3-connection-success": "החיבור ל־S3 הצליח", + "s3-enabled": "S3 הופעל", + "s3-enabled-description": "להשתמש ב־S3 של AWS או ב־MinIO לאחסון קבצים", + "s3-endpoint": "נקודת קצה ל־S3", + "s3-endpoint-description": "כתובת נקודת גישה של S3 (למשל: s3.amazonaws.com או minio.example.com)", + "s3-minio-storage": "אחסון S3/MinIO", + "s3-port": "פתחת S3", + "s3-port-description": "מספר פתחה בנקודת הגישה ל־S3", + "s3-region": "איזור (Region) S3", + "s3-region-description": "אזור (Region) ב־S3 של AWS (למשל: us-east-1)", + "s3-secret-key": "מפתח סודי (Secret Key) ל־S3", + "s3-secret-key-description": "מפתח סודי (Secret Key) ל־S3 של AWS לאימות", + "s3-secret-key-placeholder": "נא למלא מפתח סודי (Secret Key) ל־S3", + "s3-secret-key-required": "צריך מפתח סודי (Secret Key) ל־S3", + "s3-settings-save-failed": "שמירת הגדרות S3 נכשלה", + "s3-settings-saved": "הגדרות S3 נשמרו בהצלחה", + "s3-ssl-enabled": "SSL פעיל ל־S3", + "s3-ssl-enabled-description": "להשתמש ב־SSL/TLS לחיבורי S3", + "save-s3-settings": "שמירת הגדרות S3", + "schedule-board-archive": "תזמון העברה של לוח לארכיון", + "schedule-board-backup": "תזמון גיבוי לוח", + "schedule-board-cleanup": "תזמון ניקיון לוח", + "scheduled-board-operations": "תזמון פעולות לוח", + "start-all-migrations": "התחלת כל ההסבות", + "stop-all-migrations": "עצירת כל ההסבות", + "test-s3-connection": "בדיקת חיבור ל־S3", + "writable-path": "נתיב לכתיבה", + "writable-path-description": "נתיב תיקיית בסיס לאחסון קבצים", + "add-job": "הוספת משימה", + "attachment-migration": "הסבה צרופות", + "attachment-monitoring": "מעקב צרופות", + "attachment-settings": "הגדרות צרופות", + "attachment-storage-settings": "הגדרות אחסון", + "automatic-migration": "הסבה אוטומטית", + "back-to-settings": "חזרה להגדרות", + "board-id": "מזהה לוח", + "board-migration": "הסבת לוחות", + "board-migrations": "הסבות לוחות", + "card-show-lists-on-minicard": "הצגת רשימות בכרטיסון", + "comprehensive-board-migration": "הסבת לוחות נרחבת", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "כרטיסים אבודים", + "lost-cards-list": "פריטים משוחזרים", + "restore-lost-cards-migration": "שחזור כרטיסים אבודים", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "הושלם", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "ההסבה נכשלה", + "migrations": "הסבות", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "סך כל ההתקדמות", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "מצב", + "migration-progress-details": "פרטים", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "ניקיון", + "cleanup-old-jobs": "ניקוי משימות ישנות", + "completed": "הושלמה", + "conversion-info-text": "ההמרה הזאת מתבצעת פעם אחת בכל לוח והיא משפרת את הביצועים. אפשר להמשיך להשתמש בלוח כרגיל.", + "converting-board": "הלוח עובר המרה", + "converting-board-description": "מבנה הלוח מומר לשיפור היכולות. הפעולה הזאת עלולה לארוך מספר דקות.", + "cpu-cores": "ליבות מעבד", + "cpu-usage": "שימוש במעבד", + "current-action": "פעולה נוכחית", + "database-migration": "הסבת מסד נתונים", + "database-migration-description": "עדכון מבנה מסד הנתונים מתעדכן לשיפור היכולות והביצועים. התהליך הזה עלול לארוך כמה דקות.", + "database-migrations": "הסבות מסד נתונים", + "days-old": "גיל בימים", + "duration": "משך", + "errors": "שגיאות", + "estimated-time-remaining": "הערכת הזמן שנותר", + "every-1-day": "כל יום", + "every-1-hour": "כל שעה", + "every-1-minute": "כל דקה", + "every-10-minutes": "כל 10 דקות", + "every-30-minutes": "כל חצי שעה", + "every-5-minutes": "כל 5 דקות", + "every-6-hours": "כל 6 שעות", + "export-monitoring": "מעקב אחר ייצוא", + "filesystem-attachments": "צרופות מערכת קבצים", + "filesystem-size": "גודל מערכת קבצים", + "filesystem-storage": "אחסון מערכת קבצים", + "force-board-scan": "אילוץ סריקת הלוח", + "gridfs-attachments": "צרופות GridFS", + "gridfs-size": "גודל GridFS", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "הסתרת רשימה בכרטיסון", + "idle-migration": "הסבה בהמתנה", + "job-description": "תיאור משימה", + "job-details": "פרטי משימה", + "job-name": "שם משימה", + "job-queue": "תור משימות", + "last-run": "ריצה אחרונה", + "max-concurrent": "מקביליות מרבית", + "memory-usage": "שימוש בזיכרון", + "migrate-all-to-filesystem": "הסבה של הכול למערכת הקבצים", + "migrate-all-to-gridfs": "הסבה של הכול ל־GridFS", + "migrate-all-to-s3": "הסבה של הכול ל־S3", + "migrated-attachments": "צרופות שעברו הסבה", + "migration-batch-size": "גודל סדרה מרוכזת", + "migration-batch-size-description": "מספר הצרופות לעיבוד בכל סדרה מרוכזת (1‏-100)", + "migration-cpu-threshold": "סף מעבד (%)", + "migration-cpu-threshold-description": "להשהות את ההסבה כאשר השימוש במעבד חורג מהאחוז הזה (10‏-90)", + "migration-delay-ms": "השהייה (מילישניות/אלפיות השניה)", + "migration-delay-ms-description": "השהיה בין הסדרות המרוכזות במילישניות/אלפיות השנייה (100-‏10000)", + "migration-detector": "מזהה הסבות", + "migration-info-text": "הסבות מסד נתונים מתבצעות פעם אחת ומשפרות את ביצועי המערכת. התהליך ממשיך ברקע אפילו אם הדפדפן ייסגר.", + "migration-log": "יומן הסבה", + "migration-markers": "סמני הסבה", + "migration-resume-failed": "המשך ההסבה נכשל", + "migration-resumed": "ההסבה המשיכה", + "migration-steps": "שלבי הסבה", + "migration-warning-text": "נא לא לסגור את הדפדפן שלך במהלך ההסבה. התהליך ימשיך ברקע אך ייקח לו זמן ארוך יותר להסתיים.", + "monitoring-export-failed": "ייצוא נתוני המעקב נכשל", + "monitoring-refresh-failed": "רענון נתוני המעקב נכשל", + "next": "הבא", + "next-run": "הריצה הבאה", + "of": "מתוך", + "operation-type": "סוג הפעולה", + "overall-progress": "סך כל ההתקדמות", + "page": "עמוד", + "pause-migration": "השהיית הסבה", + "previous": "הקודם", + "refresh": "ריענון", + "refresh-monitoring": "ריענון מעקב", + "remaining-attachments": "צרופות שנותרו", + "resume-migration": "המשך ההסבה", + "run-once": "הרצה חד־פעמית", + "s3-attachments": "צרופות ב־S3", + "s3-size": "גודל ב־S3", + "s3-storage": "S3", + "scanning-status": "מצב סריקה", + "schedule": "לוח זמנים", + "search-boards-or-operations": "חיפוש לוחות או פעולות…", + "show-list-on-minicard": "הצגת רשימה בכרטיסון", + "showing": "מוצג", + "start-test-operation": "התחלת פעולת בדיקה", + "start-time": "מועד התחלה", + "step-progress": "התקדמות שלב", + "stop-migration": "עצירת ההסבה", + "storage-distribution": "ביזור מסד נתונים", + "system-resources": "משאבי מערכת", + "total-attachments": "סך כל הצרופות", + "total-operations": "סך כל הפעולות", + "total-size": "גודל כולל", + "unmigrated-boards": "לוחות שלא הוסבו", + "weight": "משקל", + "idle": "בהמתנה", + "complete": "הושלם", + "cron": "מתזמן" } diff --git a/imports/i18n/data/hi-IN.i18n.json b/imports/i18n/data/hi-IN.i18n.json index df36242af..727186475 100644 --- a/imports/i18n/data/hi-IN.i18n.json +++ b/imports/i18n/data/hi-IN.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "टिप्पणी हटा दी गई", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "खाका", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "संलग्न करें", @@ -190,7 +202,9 @@ "board-view-collapse": "संक्षिप्त करें", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "उदाहरण के लिए “बाल्टी सूची” की तरह", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "रद्द करें", "card-archived": "यह कार्ड संग्रह करने के लिए ले जाया गया है ।", "board-archived": "यह बोर्ड संग्रह करने के लिए ले जाया जाता है ।", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[{\"title\":\"पहला कार्ड शीर्षक\",\"description\":\"पहला कार्ड विवरण\"},{\"title\":\"दूसरा कार्ड शीर्षक\",\"description\":\"दूसरा कार्ड विवरण\"},{\"title\":\"अंतिम कार्ड शीर्षक\",\"description\":\"अंतिम कार्ड विवरण\" }]", "create": "निर्माण करना", "createBoardPopup-title": "बोर्ड निर्माण करना", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "बोर्ड आयात", "createLabelPopup-title": "नामपत्र निर्माण", "createCustomField": "क्षेत्र निर्माण", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "प्रचलन क्षेत्र", "date": "दिनांक", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "संपादित करें Notification", "editProfilePopup-title": "संपादित करें Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "All lists, कार्ड,नामपत्र , और activities हो जाएगा deleted और you won't be able तक recover the बोर्ड contents. There is no undo.", "boardDeletePopup-title": "मिटाएँ बोर्ड?", "delete-board": "मिटाएँ बोर्ड", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ बोर्ड", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks व्यवस्था", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "बोर्ड Subtasks व्यवस्था", + "boardSubtaskSettingsPopup-title": "Subtasks व्यवस्था", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks तक यह बोर्ड:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/hi.i18n.json b/imports/i18n/data/hi.i18n.json index 95ebb1655..854bfc00d 100644 --- a/imports/i18n/data/hi.i18n.json +++ b/imports/i18n/data/hi.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "टिप्पणी हटा दी गई", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "खाका", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "संलग्न करें", @@ -190,7 +202,9 @@ "board-view-collapse": "संक्षिप्त करें", "board-view-gantt": "Gantt", "board-view-lists": "सूचियाँ", - "bucket-example": "उदाहरण के लिए “बाल्टी सूची” की तरह", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "रद्द करें", "card-archived": "यह कार्ड संग्रह करने के लिए ले जाया गया है ।", "board-archived": "यह बोर्ड संग्रह करने के लिए ले जाया जाता है ।", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[{\"title\":\"पहला कार्ड शीर्षक\",\"description\":\"पहला कार्ड विवरण\"},{\"title\":\"दूसरा कार्ड शीर्षक\",\"description\":\"दूसरा कार्ड विवरण\"},{\"title\":\"अंतिम कार्ड शीर्षक\",\"description\":\"अंतिम कार्ड विवरण\" }]", "create": "निर्माण करना", "createBoardPopup-title": "बोर्ड निर्माण करना", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "बोर्ड आयात", "createLabelPopup-title": "नामपत्र निर्माण", "createCustomField": "क्षेत्र निर्माण", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "प्रचलन क्षेत्र", "date": "दिनांक", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "संपादित करें Notification", "editProfilePopup-title": "संपादित करें Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "All lists, कार्ड,नामपत्र , और activities हो जाएगा deleted और you won't be able तक recover the बोर्ड contents. There is no undo.", "boardDeletePopup-title": "मिटाएँ बोर्ड?", "delete-board": "मिटाएँ बोर्ड", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ बोर्ड", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks व्यवस्था", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "बोर्ड Subtasks व्यवस्था", + "boardSubtaskSettingsPopup-title": "Subtasks व्यवस्था", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks तक यह बोर्ड:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/hr.i18n.json b/imports/i18n/data/hr.i18n.json index fbdb4e29b..475e99049 100644 --- a/imports/i18n/data/hr.i18n.json +++ b/imports/i18n/data/hr.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "obrisan komentar %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Predlošci", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Dodaj privitak", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Liste", - "bucket-example": "Na primjer, poput \"Liste zadataka\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Odustani", "card-archived": "Ova kartica prebačena je u arhivu.", "board-archived": "Ova ploča prebačena je u arhivu.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Dodaj", "createBoardPopup-title": "Dodaj ploču", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Uvezi ploču", "createLabelPopup-title": "Dodaj oznaku", "createCustomField": "Dodaj polje", @@ -354,6 +369,10 @@ "custom-field-text": "Tekst", "custom-fields": "Prilagođena polja", "date": "Datum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Odustani", "default-avatar": "Zadani avatar", "delete": "Obriši", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Uredi profil", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Obriši ploču", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Zadano", "defaultdefault": "Zadano", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "od", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/hu.i18n.json b/imports/i18n/data/hu.i18n.json index 6d50b8903..1f2e257be 100644 --- a/imports/i18n/data/hu.i18n.json +++ b/imports/i18n/data/hu.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "törölte ezt a megjegyzést: %s", "activity-receivedDate": "átírta az \"érkezett\" dátumot erről: %s erre: %s", "activity-startDate": "átírta az \"elkezdve\" dátumot erről: %s erre: %s", + "allboards.starred": "Starred", + "allboards.templates": "Sablonok", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "átírta a *határidő* dátumát erről: %s erre: %s", "activity-endDate": "átírta a \"befejezés\" dátumát erről: %s erre: %s", "add-attachment": "Melléklet hozzáadása", @@ -190,7 +202,9 @@ "board-view-collapse": "Összecsukás", "board-view-gantt": "Gantt", "board-view-lists": "Listák", - "bucket-example": "Mint például „Bakancslista”", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Mégse", "card-archived": "A kártya az archív kártyák közé kerül.", "board-archived": "Ezt a Táblát archiválták", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Első kártya címe\", \"description\":\"Első kártya leírása\"}, {\"title\":\"Második kártya címe\",\"description\":\"Második kártya leírása\"},{\"title\":\"Utolsó kártya címe\",\"description\":\"Utolsó kártya leírása\"} ]", "create": "Létrehozás", "createBoardPopup-title": "Tábla létrehozása", + "createTemplateContainerPopup-title": "Sablon Tároló hozzáadása", "chooseBoardSourcePopup-title": "Tábla importálása", "createLabelPopup-title": "Címke létrehozása", "createCustomField": "Mező létrehozása", @@ -354,6 +369,10 @@ "custom-field-text": "Szöveg", "custom-fields": "Egyéni mezők", "date": "Dátum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Elutasítás", "default-avatar": "Alapértelmezett avatár", "delete": "Törlés", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Értesítés szerkesztése", "editProfilePopup-title": "Edit Profile", "email": "E-mail", + "email-address": "Email Address", "email-enrollAccount-subject": "Létrejött a profilja a következő oldalon: __siteName__", "email-enrollAccount-text": "Kedves __user__!\n\nA szolgáltatás használatának megkezdéséhez egyszerűen kattintson a lenti hivatkozásra.\n\n__url__\n\nKöszönjük.", "email-fail": "Az e-mail küldése nem sikerült", @@ -748,6 +768,8 @@ "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?", "delete-board": "Tábla törlése", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Rész-feladatok ehhez a Táblához: __board__", "default": "Alapértelmezett", "defaultdefault": "Alapértelmezett", @@ -755,7 +777,7 @@ "subtask-settings": "Rész-feladat beállításai", "card-settings": "Kátya beállítások", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Tábla Rész-feladatok beállításai", + "boardSubtaskSettingsPopup-title": "Rész-feladat beállításai", "boardCardSettingsPopup-title": "Kátya beállítások", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Helyezd a Rész-feladatokat erre a Táblára:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Én", "dueCardsViewChange-choice-all": "Minden felhasználó", "dueCardsViewChange-choice-all-description": "Minden befejezetlen kártyát felsorol \"határidős\" dátummal, amihez a felhasználónak hozzáférése van.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Sérült Kártyák", "board-title-not-found": "\"%s\" nevű Tábla nem található", "swimlane-title-not-found": "\"%s\" nevű Úszósáv nem található", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Állapot", + "migration-progress-details": "Részletek", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Kész", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/hy.i18n.json b/imports/i18n/data/hy.i18n.json index bc6516d47..c16f6a92f 100644 --- a/imports/i18n/data/hy.i18n.json +++ b/imports/i18n/data/hy.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/id.i18n.json b/imports/i18n/data/id.i18n.json index 7b2740fcf..ce83f1f26 100644 --- a/imports/i18n/data/id.i18n.json +++ b/imports/i18n/data/id.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "komentar dihapus %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Klise", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Tambah Lampiran", @@ -190,7 +202,9 @@ "board-view-collapse": "Ciutkan", "board-view-gantt": "Gantt", "board-view-lists": "Daftar", - "bucket-example": "Contohnya seperti “Bucket List”", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Batal", "card-archived": "Kartu ini telah dipindahkan ke Arsip", "board-archived": "Kartu ini telah dipindahkan ke Arsip", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Buat", "createBoardPopup-title": "Buat Panel", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Buat Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Tanggal", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Tolak", "default-avatar": "Avatar standar", "delete": "Hapus", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Sunting Pemberitahuan", "editProfilePopup-title": "Sunting Profil", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Sebuah akun dibuat untuk Anda pada __siteName__", "email-enrollAccount-text": "Halo __user__,\n\nUntuk mulai menggunakan, silakan klik tautan berikut.\n\n__url__\n\nTerima kasih.", "email-fail": "Surel gagal terkirim", @@ -748,6 +768,8 @@ "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?", "delete-board": "Hapus Papan", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Standar", "defaultdefault": "Standar", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Pengaturan Kartu", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Pengaturan Kartu", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "dari", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ig.i18n.json b/imports/i18n/data/ig.i18n.json index 5ea4fae02..580fbb197 100644 --- a/imports/i18n/data/ig.i18n.json +++ b/imports/i18n/data/ig.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/it.i18n.json b/imports/i18n/data/it.i18n.json index c09c3f3ef..e82709ca0 100644 --- a/imports/i18n/data/it.i18n.json +++ b/imports/i18n/data/it.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "commento eliminato %s", "activity-receivedDate": "ha modificato la data di ricevuta a %s di %s", "activity-startDate": "ha modificato la data di inizio a %s di %s", + "allboards.starred": "Starred", + "allboards.templates": "Template", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "ha modificato la data di scadenza a %s di %s", "activity-endDate": "ha modificato la data di fine a %s di %s", "add-attachment": "Aggiungi allegato", @@ -190,7 +202,9 @@ "board-view-collapse": "Comprimi", "board-view-gantt": "Gantt", "board-view-lists": "Liste", - "bucket-example": "Come \"una lista di cose da fare\" per esempio", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancella", "card-archived": "Questa scheda è stata spostata nell'archivio", "board-archived": "Questa bacheca è stata spostata nell'archivio", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Titolo prima scheda\", \"description\":\"Descrizione prima scheda\"}, {\"title\":\"Titolo seconda scheda\",\"description\":\"Descrizione seconda scheda\"},{\"title\":\"Titolo ultima scheda\",\"description\":\"Descrizione ultima scheda\"} ]", "create": "Crea", "createBoardPopup-title": "Crea bacheca", + "createTemplateContainerPopup-title": "Aggiungi contenitore di Template", "chooseBoardSourcePopup-title": "Importa bacheca", "createLabelPopup-title": "Crea etichetta", "createCustomField": "Crea campo", @@ -354,6 +369,10 @@ "custom-field-text": "Testo", "custom-fields": "Campi personalizzati", "date": "Data", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Rifiuta", "default-avatar": "Avatar predefinito", "delete": "Elimina", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Modifica notifiche", "editProfilePopup-title": "Modifica profilo", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Creato un account per te su __siteName__", "email-enrollAccount-text": "Ciao __user__,\n\nPer iniziare ad utilizzare il servizio, clicca sul link seguente:\n\n__url__\n\nGrazie.", "email-fail": "Invio email fallito", @@ -748,6 +768,8 @@ "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?", "delete-board": "Elimina bacheca", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Sottocompiti per la bacheca __board__", "default": "Predefinito", "defaultdefault": "Predefinito", @@ -755,7 +777,7 @@ "subtask-settings": "Impostazioni sotto-compiti", "card-settings": "Impostazioni scheda", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Impostazioni sotto-compiti della bacheca", + "boardSubtaskSettingsPopup-title": "Impostazioni sotto-compiti", "boardCardSettingsPopup-title": "Impostazioni scheda", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposita i sotto compiti in questa bacheca", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "Tutti gli utenti", "dueCardsViewChange-choice-all-description": "Visualizza tutte le schede non completate con una data di *scadenza* dalle bacheche in cui l'utente ha il permesso.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Schede danneggiate", "board-title-not-found": "Bacheca '%s' non trovata.", "swimlane-title-not-found": "Swimlane '%s' non trovata.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "L'utente è attivo - clicca per disattivarlo", "admin-people-user-inactive": "L'utente è inattivo: clicca per attivarlo", "accounts-lockout-all-users-unlocked": "Tutti gli utenti bloccati sono stati sbloccati", - "accounts-lockout-unlock-all": "Sblocca Tutti" + "accounts-lockout-unlock-all": "Sblocca Tutti", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Completato", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Stato", + "migration-progress-details": "Dettagli", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completato/a", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "di", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Peso", + "idle": "Inattivo", + "complete": "Completato", + "cron": "Pianificazione" } diff --git a/imports/i18n/data/ja-HI.i18n.json b/imports/i18n/data/ja-HI.i18n.json index 9ef8d5725..ef8a053d6 100644 --- a/imports/i18n/data/ja-HI.i18n.json +++ b/imports/i18n/data/ja-HI.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -177,20 +189,22 @@ "boardChangeViewPopup-title": "Board View", "boards": "Boards", "board-view": "Board View", - "desktop-mode": "Desktop Mode", - "mobile-mode": "Mobile Mode", + "desktop-mode": "デスクトップモード", + "mobile-mode": "モバイルモード", "mobile-desktop-toggle": "Toggle between Mobile and Desktop Mode", - "zoom-in": "Zoom In", - "zoom-out": "Zoom Out", + "zoom-in": "拡大", + "zoom-out": "縮小", "click-to-change-zoom": "Click to change zoom level", "zoom-level": "Zoom Level", - "enter-zoom-level": "Enter zoom level (50-300%):", + "enter-zoom-level": "拡大率(50-300%)", "board-view-cal": "Calendar", "board-view-swimlanes": "Swimlanes", "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "ロックされているすべてのユーザのロックが解除されました。", - "accounts-lockout-unlock-all": "すべてロック解除" + "accounts-lockout-unlock-all": "すべてロック解除", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "リストをリストア", + "step-restore-cards": "カードをリストア", + "step-restore-swimlanes": "スイムレーンをリストア", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ja.i18n.json b/imports/i18n/data/ja.i18n.json index 1f687fe48..5403ebdcc 100644 --- a/imports/i18n/data/ja.i18n.json +++ b/imports/i18n/data/ja.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "コメント %s を削除しました", "activity-receivedDate": "受付日を %s に変更しました / %s", "activity-startDate": "開始日を %s に変更しました / %s", + "allboards.starred": "Starred", + "allboards.templates": "テンプレート", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "期限日を %s に変更しました / %s", "activity-endDate": "終了日を %s に変更しました / %s", "add-attachment": "添付ファイルを追加", @@ -177,20 +189,22 @@ "boardChangeViewPopup-title": "ボード表示", "boards": "ボード", "board-view": "ボード表示", - "desktop-mode": "Desktop Mode", - "mobile-mode": "Mobile Mode", + "desktop-mode": "デスクトップモード", + "mobile-mode": "モバイルモード", "mobile-desktop-toggle": "Toggle between Mobile and Desktop Mode", - "zoom-in": "Zoom In", - "zoom-out": "Zoom Out", + "zoom-in": "拡大", + "zoom-out": "縮小", "click-to-change-zoom": "Click to change zoom level", "zoom-level": "Zoom Level", - "enter-zoom-level": "Enter zoom level (50-300%):", + "enter-zoom-level": "拡大率(50-300%)", "board-view-cal": "カレンダー", "board-view-swimlanes": "スイムレーン", "board-view-collapse": "折りたたむ", "board-view-gantt": "ガント", "board-view-lists": "リスト", - "bucket-example": "例:バケットリスト", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "キャンセル", "card-archived": "このカードをアーカイブしました。", "board-archived": "このボードをアーカイブしました。", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"1つ目のカードタイトル\", \"description\":\"1つ目のカードの説明\"}, {\"title\":\"2つ目のカードタイトル\",\"description\":\"2つ目のカードの説明\"},{\"title\":\"最後のカードタイトル\",\"description\":\"最後のカードの説明\"} ]", "create": "作成", "createBoardPopup-title": "ボードの作成", + "createTemplateContainerPopup-title": "テンプレートコンテナを追加", "chooseBoardSourcePopup-title": "ボードをインポート", "createLabelPopup-title": "ラベルの作成", "createCustomField": "フィールドを作成", @@ -354,6 +369,10 @@ "custom-field-text": "テキスト", "custom-fields": "カスタムフィールド", "date": "日付", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "拒否", "default-avatar": "デフォルトのアバター", "delete": "削除", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "通知の変更", "editProfilePopup-title": "プロフィールの編集", "email": "メールアドレス", + "email-address": "Email Address", "email-enrollAccount-subject": "__siteName__であなたのアカウントが作成されました", "email-enrollAccount-text": "こんにちは、__user__さん。\n\nサービスを開始するには、以下をクリックしてください。\n\n__url__\n\nよろしくお願いします。", "email-fail": "メールの送信に失敗しました", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "すべてのリスト、カード、ラベル、アクティビティは削除され、ボードの内容を元に戻すことができません。", "boardDeletePopup-title": "ボードを削除しますか?", "delete-board": "ボードを削除", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "__board__ ボードのサブタスク", "default": "デフォルト", "defaultdefault": "デフォルト", @@ -755,7 +777,7 @@ "subtask-settings": "サブタスク設定", "card-settings": "カード設定", "minicard-settings": "ミニカード設定", - "boardSubtaskSettingsPopup-title": "ボードのサブタスク設定", + "boardSubtaskSettingsPopup-title": "サブタスク設定", "boardCardSettingsPopup-title": "カード設定", "boardMinicardSettingsPopup-title": "ミニカード設定", "deposit-subtasks-board": "サブタスクの作成先ボード:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "自分", "dueCardsViewChange-choice-all": "全ユーザー", "dueCardsViewChange-choice-all-description": "ユーザーに権限のあるボードから、期限が切れたすべての未完了のカードを表示します。", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "壊れたカード", "board-title-not-found": "ボード「%s」は見つかりませんでした。", "swimlane-title-not-found": "スイムレーン「%s」は見つかりませんでした。", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "ロックされているすべてのユーザのロックが解除されました。", - "accounts-lockout-unlock-all": "すべてロック解除" + "accounts-lockout-unlock-all": "すべてロック解除", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "完了", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "ステータス", + "migration-progress-details": "詳細", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "リストをリストア", + "step-restore-cards": "カードをリストア", + "step-restore-swimlanes": "スイムレーンをリストア", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "完了した時", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "/", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "重み", + "idle": "アイドル", + "complete": "完了", + "cron": "スケジュール" } diff --git a/imports/i18n/data/ka.i18n.json b/imports/i18n/data/ka.i18n.json index e546fc898..2c6c8ebfa 100644 --- a/imports/i18n/data/ka.i18n.json +++ b/imports/i18n/data/ka.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "მიბმული ფაილის დამატება", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "ჩამონათვალი", - "bucket-example": "მაგალითად “Bucket List”", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "გაუქმება", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"სათაური\": \"პირველი ბარათის სათაური\", \"აღწერა\":\"პირველი ბარათის აღწერა\"}, {\"სათაური\":\"მეორე ბარათის სათაური\",\"აღწერა\":\"მეორე ბარათის აღწერა\"},{\"სათაური\":\"ბოლო ბარათის სათაური\",\"აღწერა\":\"ბოლო ბარათის აღწერა\"} ]", "create": "შექმნა", "createBoardPopup-title": "დაფის შექმნა", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "დაფის იმპორტი", "createLabelPopup-title": "ნიშნის შექმნა", "createCustomField": "ველის შექმნა", @@ -354,6 +369,10 @@ "custom-field-text": "ტექსტი", "custom-fields": "მომხმარებლის ველი", "date": "თარიღი", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "უარყოფა", "default-avatar": "სტანდარტული ავატარი", "delete": "წაშლა", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "შეტყობინებების შესწორება", "editProfilePopup-title": "პროფილის შესწორება", "email": "ელ.ფოსტა", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "მოგესალმებით __user__,\n\nამ სერვისის გამოსაყენებლად დააკლიკეთ ქვედა ბმულს.\n\n__url__\n\nმადლობა.", "email-fail": "ელ.ფოსტის გაგზავნა ვერ მოხერხდა", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "ყველა ჩამონათვალი, ბარათი, ნიშანი და აქტივობა წაიშლება და თქვენ ვეღარ შეძლებთ მის აღდგენას.", "boardDeletePopup-title": "წავშალოთ დაფა?", "delete-board": "დაფის წაშლა", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "ქვესაქმიანობა __board__ დაფისთვის", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "ქვესაქმიანობების პარამეტრები", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "ქვესაქმიანობების პარამეტრები", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/km.i18n.json b/imports/i18n/data/km.i18n.json index 922132936..a88c7f2c1 100644 --- a/imports/i18n/data/km.i18n.json +++ b/imports/i18n/data/km.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ko-KR.i18n.json b/imports/i18n/data/ko-KR.i18n.json index 3b4ebe4e1..c0dbd8074 100644 --- a/imports/i18n/data/ko-KR.i18n.json +++ b/imports/i18n/data/ko-KR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ko.i18n.json b/imports/i18n/data/ko.i18n.json index c7b59db6d..0dea02432 100644 --- a/imports/i18n/data/ko.i18n.json +++ b/imports/i18n/data/ko.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "삭제된 댓글", "activity-receivedDate": "수신 날짜를 %s의 %s로 수정함", "activity-startDate": "시작 날짜가 %s의 %s로 수정됨", + "allboards.starred": "Starred", + "allboards.templates": "템플릿", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "마감 날짜가 %s의 %s로 수정됨", "activity-endDate": "종료 날짜가 %s의 %s로 수정됨", "add-attachment": "첨부파일 추가", @@ -190,7 +202,9 @@ "board-view-collapse": "접기", "board-view-gantt": "간트", "board-view-lists": "목록들", - "bucket-example": "예: “프로젝트 이름“ 입력", + "bucket-example": "예: \"꼭 하고싶은 일 목록\"", + "calendar-previous-month-label": "이전 월", + "calendar-next-month-label": "다음 월", "cancel": "취소", "card-archived": "이 카드는 보관함으로 이동 되었습니다.", "board-archived": "이 보드는 보관함으로 이동 되었습니다.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "생성", "createBoardPopup-title": "보드 생성", + "createTemplateContainerPopup-title": "템플릿 컨테이너 추가", "chooseBoardSourcePopup-title": "보드 가져오기", "createLabelPopup-title": "라벨 생성", "createCustomField": "필드 생성", @@ -354,6 +369,10 @@ "custom-field-text": "텍스트", "custom-fields": "사용자정의 항목", "date": "날짜", + "date-format": "날짜 형식", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "쇠퇴", "default-avatar": "기본 아바타", "delete": "삭제", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "알림 수정", "editProfilePopup-title": "프로필 변경", "email": "이메일", + "email-address": "이메일 주소", "email-enrollAccount-subject": "__siteName__에 계정 생성이 완료되었습니다.", "email-enrollAccount-text": "안녕하세요. __user__님,\n\n시작하려면 아래링크를 클릭해 주세요.\n\n__url__\n\n감사합니다.", "email-fail": "이메일 전송 실패", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "모든 목록, 카드, 레이블 및 활동이 삭제되고 보드 내용을 복구할 수 없습니다. 실행 취소는 불가능합니다.", "boardDeletePopup-title": "보드 삭제?", "delete-board": "보드 삭제", + "delete-duplicate-lists": "중복 목록 삭제", + "delete-duplicate-lists-confirm": "확실합니까? 이렇게 하면 이름이 같고 카드가 없는 모든 중복 목록이 삭제됩니다.", "default-subtasks-board": "Subtasks for __board__ board", "default": "기본", "defaultdefault": "기본", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "카드 설정", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "카드 설정", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "만료된 카드를 찾을 수 없음", + "dueCards-noResults-description": "현재 마감일이 있는 카드가 없습니다.", "broken-cards": "Broken Cards", "board-title-not-found": "보드 %s 을 찾을 수 없습니다.", "swimlane-title-not-found": "Swimlane %s 을 찾을 수 없습니다.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "완료", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "상세", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "완료", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "가중치", + "idle": "유휴", + "complete": "완료", + "cron": "스케줄러" } diff --git a/imports/i18n/data/lt.i18n.json b/imports/i18n/data/lt.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/lt.i18n.json +++ b/imports/i18n/data/lt.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/lv.i18n.json b/imports/i18n/data/lv.i18n.json index 1a829eeea..b68d6e47f 100644 --- a/imports/i18n/data/lv.i18n.json +++ b/imports/i18n/data/lv.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "dzēsa komentāru %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Sagataves", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Pievienot failu", @@ -190,7 +202,9 @@ "board-view-collapse": "Sakļaut", "board-view-gantt": "Gantt", "board-view-lists": "Saraksti", - "bucket-example": "Piemēram \"Izdarāmie darbi\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Atcelt", "card-archived": "Šī kartiņa ir pārvietota uz arhīvu", "board-archived": "Šis dēlis ir pārvietots uz arhīvu", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Pirmās kartiņas virsraksts\", \"description\":\"Pirmās kartiņas apraksts}, {\"title\":\"Otrās kartiņas virsraksts\",\"description\":\"Otrās kartiņas apraksts\"},{\"title\":\"Pēdējās kartiņas virsraksts\",\"description\":\"Pēdējās kartiņas apraksts\"} ]", "create": "Izveidot", "createBoardPopup-title": "Izveidot dēli", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importēt dēli", "createLabelPopup-title": "Izveidot birku", "createCustomField": "Izveidot lauku", @@ -354,6 +369,10 @@ "custom-field-text": "Teksts", "custom-fields": "Lauki", "date": "Datums", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Noraidīt", "default-avatar": "Noklusētais attēls", "delete": "Dzēst", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Labot ziņojumu", "editProfilePopup-title": "Labot profilu", "email": "E-pasts", + "email-address": "Email Address", "email-enrollAccount-subject": "Izveidots profils iekš __siteName__", "email-enrollAccount-text": "Sveiki, __user__,\n\nLai sāktu izmantot servisu, vienkārši spied saiti zemāk.\n\n__url__\n\nPaldies.", "email-fail": "E-pasta sūtīšana neizdevās", @@ -748,6 +768,8 @@ "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?", "delete-board": "Dzēst dēli", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Apakšuzdevumi priekš __board__ dēļa", "default": "Noklusēts", "defaultdefault": "Noklusēts", @@ -755,7 +777,7 @@ "subtask-settings": "Apakšuzdevumu iestatījumi", "card-settings": "Kartiņas iestatījumi", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Dēļa apakšuzdevumu iestatījumi", + "boardSubtaskSettingsPopup-title": "Apakšuzdevumu iestatījumi", "boardCardSettingsPopup-title": "Kartiņas iestatījumi", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Noguldīt apakšuzdevumus uz šo dēli:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Statuss", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Pabeigts", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "no", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/mk.i18n.json b/imports/i18n/data/mk.i18n.json index 9d5295af4..5ac7384f0 100644 --- a/imports/i18n/data/mk.i18n.json +++ b/imports/i18n/data/mk.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Додај прилог", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Листи", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Откажи", "card-archived": "Тази карта е преместена во Архива.", "board-archived": "Това табло е преместено во Архива.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Креирај", "createBoardPopup-title": "Креирај Табло", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Импортирай Табло", "createLabelPopup-title": "Креирај Табло", "createCustomField": "Креирај Поле", @@ -354,6 +369,10 @@ "custom-field-text": "Текст", "custom-fields": "Собствени полета", "date": "Дата", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Откажи", "default-avatar": "Основен аватар", "delete": "Избриши", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Промени известията", "editProfilePopup-title": "Промяна на профила", "email": "Имейл", + "email-address": "Email Address", "email-enrollAccount-subject": "Ваш профил беше създаден на __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Неуспешно изпращане на имейла", @@ -748,6 +768,8 @@ "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": "Изтрий таблото", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Подзадачи за табло __board__", "default": "по подразбиране", "defaultdefault": "по подразбиране", @@ -755,7 +777,7 @@ "subtask-settings": "Настройки на Подзадачите", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Настройки за Подзадачите за това Табло", + "boardSubtaskSettingsPopup-title": "Настройки на Подзадачите", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/mn.i18n.json b/imports/i18n/data/mn.i18n.json index 9468c3f37..eb1dbc66d 100644 --- a/imports/i18n/data/mn.i18n.json +++ b/imports/i18n/data/mn.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Хавсралт нэмэх", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Үүсгэх", "createBoardPopup-title": "Самбар үүсгэх", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Шошго үүсгэх", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Мэдэгдэл тохируулах", "editProfilePopup-title": "Бүртгэл засварлах", "email": "Имэйл", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ms-MY.i18n.json b/imports/i18n/data/ms-MY.i18n.json index 4fe4da717..7c102b2ef 100644 --- a/imports/i18n/data/ms-MY.i18n.json +++ b/imports/i18n/data/ms-MY.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -89,13 +101,13 @@ "setListWidthPopup-title": "Tetapkan Lebar", "set-list-width": "Tetapkan Lebar", "set-list-width-value": "Tetapkan lebar minimum dan maksimum (piksel)", - "list-width-error-message": "List widths must be integers greater than 100", - "keyboard-shortcuts-enabled": "Keyboard shortcuts enabled. Click to disable.", - "keyboard-shortcuts-disabled": "Keyboard shortcuts disabled. Click to enable.", - "setSwimlaneHeightPopup-title": "Set Swimlane Height", - "set-swimlane-height": "Set Swimlane Height", - "set-swimlane-height-value": "Swimlane Height (pixels)", - "swimlane-height-error-message": "Swimlane height must be a positive integer", + "list-width-error-message": "Lebar senarai mestilah integer lebih besar dari 100", + "keyboard-shortcuts-enabled": "Pintasan papan kekunci didayakan. Klik untuk batal.", + "keyboard-shortcuts-disabled": "Pintasan papan kekunci didayakan. Klik untuk batal.", + "setSwimlaneHeightPopup-title": "Tetapkan ketinggian Swimlane", + "set-swimlane-height": "Tetapkan ketinggian Swimlane", + "set-swimlane-height-value": "Ketinggian Swimlane (piksel)", + "swimlane-height-error-message": "Ketinggian Swimlane mestilah integer positif", "add-swimlane": "Add Swimlane", "add-subtask": "Add Subtask", "add-checklist": "Add Checklist", @@ -103,10 +115,10 @@ "close-add-checklist-item": "Close add an item to checklist form", "close-edit-checklist-item": "Close edit an item to checklist form", "convertChecklistItemToCardPopup-title": "Convert to Card", - "add-cover": "Add cover image to minicard", + "add-cover": "Tambah imej depan pada kad mini", "add-label": "Add Label", "add-list": "Tambah Senarai", - "add-after-list": "Add After List", + "add-after-list": "Tambah selepas senarai", "add-members": "Tambah Ahli", "added": "Ditambah", "addMemberPopup-title": "Ahli-ahli", @@ -125,7 +137,7 @@ "archive": "Move to Archive", "archive-all": "Move All to Archive", "archive-board": "Move Board to Archive", - "archive-board-confirm": "Are you sure you want to archive this board?", + "archive-board-confirm": "Anda pasti untuk mengarkibkan papan ini?", "archive-card": "Move Card to Archive", "archive-list": "Move List to Archive", "archive-swimlane": "Move Swimlane to Archive", @@ -147,13 +159,13 @@ "attachmentDeletePopup-title": "Delete Attachment?", "attachments": "Attachments", "auto-watch": "Automatically watch boards when they are created", - "avatar-too-big": "The avatar is too large (__size__ max)", + "avatar-too-big": "Saiz Avatar terlalu besar (__size__max)", "back": "Back", "board-change-color": "Change color", - "board-change-background-image": "Change Background Image", - "board-background-image-url": "Background Image URL", - "add-background-image": "Add Background Image", - "remove-background-image": "Remove Background Image", + "board-change-background-image": "Ubah imej latar", + "board-background-image-url": "URL imej latar", + "add-background-image": "Tambah imej latar", + "remove-background-image": "Hapus imej latar", "show-at-all-boards-page" : "Show at All Boards page", "board-info-on-my-boards" : "All Boards Settings", "boardInfoOnMyBoardsPopup-title" : "All Boards Settings", @@ -166,9 +178,9 @@ "board-public-info": "This board will be public.", "board-drag-drop-reorder-or-click-open": "Drag and drop to reorder board icons. Click board icon to open board.", "boardChangeColorPopup-title": "Change Board Background", - "boardChangeBackgroundImagePopup-title": "Change Background Image", + "boardChangeBackgroundImagePopup-title": "Ubah imej latar", "allBoardsChangeColorPopup-title": "Change color", - "allBoardsChangeBackgroundImagePopup-title": "Change Background Image", + "allBoardsChangeBackgroundImagePopup-title": "Ubah imej latar", "boardChangeTitlePopup-title": "Rename Board", "boardChangeVisibilityPopup-title": "Change Visibility", "boardChangeWatchPopup-title": "Change Watch", @@ -177,20 +189,22 @@ "boardChangeViewPopup-title": "Board View", "boards": "Boards", "board-view": "Board View", - "desktop-mode": "Desktop Mode", - "mobile-mode": "Mobile Mode", - "mobile-desktop-toggle": "Toggle between Mobile and Desktop Mode", - "zoom-in": "Zoom In", - "zoom-out": "Zoom Out", - "click-to-change-zoom": "Click to change zoom level", - "zoom-level": "Zoom Level", - "enter-zoom-level": "Enter zoom level (50-300%):", + "desktop-mode": "Mod Desktop", + "mobile-mode": "Mod Mudah Alih", + "mobile-desktop-toggle": "Tukar antara mod mudah alih dan desktop", + "zoom-in": "Zum masuk", + "zoom-out": "Zum keluar", + "click-to-change-zoom": "Klik untuk ubah aras zum", + "zoom-level": "Aras zum", + "enter-zoom-level": "Masukkan aras zum (50-300%)", "board-view-cal": "Calendar", "board-view-swimlanes": "Swimlanes", "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Contohnya \"Bucket List\"", + "calendar-previous-month-label": "Bulan Sebelum", + "calendar-next-month-label": "Bulan Depan", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -275,9 +289,9 @@ "checklists": "Checklists", "click-to-star": "Click to star this board.", "click-to-unstar": "Click to unstar this board.", - "click-to-enable-auto-width": "Auto list width disabled. Click to enable.", - "click-to-disable-auto-width": "Auto list width enabled. Click to disable.", - "auto-list-width": "Auto list width", + "click-to-enable-auto-width": "Lebar senarai lalai tidak didayakan. Klik untuk dayakan.", + "click-to-disable-auto-width": "Lebar senarai lalai didayakan. Klik untuk tidak didayakan.", + "auto-list-width": "Lebar senarai lalai.", "clipboard": "Clipboard or drag & drop", "close": "Close", "close-board": "Close Board", @@ -309,7 +323,7 @@ "color-white": "white", "color-yellow": "yellow", "unset-color": "Unset", - "comments": "Comments", + "comments": "Komen", "comment": "Comment", "comment-placeholder": "Write Comment", "comment-only": "Comment only", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Format Tarikh", + "date-format-yyyy-mm-dd": "TTTT-BB-HH", + "date-format-dd-mm-yyyy": "HH-BB-TTTT", + "date-format-mm-dd-yyyy": "BB-HH-TTTT", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Alamat Email", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -392,14 +412,14 @@ "email-sent": "Email sent", "email-verifyEmail-subject": "Verify your email address on __siteName__", "email-verifyEmail-text": "Hello __user__,\n\nTo verify your account email, simply click the link below.\n\n__url__\n\nThanks.", - "enable-vertical-scrollbars": "Enable vertical scrollbars", + "enable-vertical-scrollbars": "Dayakan bar skrol melintang", "enable-wip-limit": "Enable WIP Limit", "error-board-doesNotExist": "This board does not exist", "error-board-notAdmin": "You need to be admin of this board to do that", "error-board-notAMember": "You need to be a member of this board to do that", "error-json-malformed": "Your text is not valid JSON", "error-json-schema": "Your JSON data does not include the proper information in the correct format", - "error-csv-schema": "Your CSV(Comma Separated Values)/TSV (Tab Separated Values) does not include the proper information in the correct format ", + "error-csv-schema": "CSV(Comma Separated Values)/TSV (Tab Separated Values) anda tidak mengikut format yang betul dengan maklumat yang bersesuaian.", "error-list-doesNotExist": "This list does not exist", "error-user-doesNotExist": "This user does not exist", "error-user-notAllowSelf": "You can not invite yourself", @@ -438,7 +458,7 @@ "filter-overdue": "Overdue", "filter-due-today": "Due today", "filter-due-this-week": "Due this week", - "filter-due-next-week": "Due next week", + "filter-due-next-week": "Tamat minggu depan", "filter-due-tomorrow": "Due tomorrow", "list-filter-label": "Filter List by Title", "filter-clear": "Clear filter", @@ -567,7 +587,7 @@ "public": "Public", "public-desc": "This board is public. It's visible to anyone with the link and will show up in search engines like Google. Only people added to the board can edit.", "quick-access-description": "Star a board to add a shortcut in this bar.", - "remove-cover": "Remove cover image from minicard", + "remove-cover": "Hapus imej depan daripada kad mini", "remove-from-board": "Remove from Board", "remove-label": "Remove Label", "listDeletePopup-title": "Delete List ?", @@ -589,14 +609,14 @@ "select-board": "Select Board", "set-wip-limit-value": "Set a limit for the maximum number of tasks in this list", "setWipLimitPopup-title": "Set WIP Limit", - "shortcut-add-self": "Add yourself to current card", + "shortcut-add-self": "Tambah diri sendiri kepada kad ini", "shortcut-assign-self": "Assign yourself to current card", "shortcut-autocomplete-emoji": "Autocomplete emoji", "shortcut-autocomplete-members": "Autocomplete members", "shortcut-clear-filters": "Clear all filters", "shortcut-close-dialog": "Close Dialog", "shortcut-filter-my-cards": "Filter my cards", - "shortcut-filter-my-assigned-cards": "Filter my assigned cards", + "shortcut-filter-my-assigned-cards": "Tapis kad sendiri", "shortcut-show-shortcuts": "Bring up this shortcuts list", "shortcut-toggle-filterbar": "Toggle Filter Sidebar", "shortcut-toggle-searchbar": "Toggle Search Sidebar", @@ -631,9 +651,9 @@ "upload": "Upload", "upload-avatar": "Upload an avatar", "uploaded-avatar": "Uploaded an avatar", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "Muat naik fail", + "upload-failed": "Muat naik gagal", + "upload-completed": "Muat naik selesai", "custom-top-left-corner-logo-image-url": "Custom Top Left Corner Logo Image URL", "custom-top-left-corner-logo-link-url": "Custom Top Left Corner Logo Link URL", "custom-top-left-corner-logo-height": "Custom Top Left Corner Logo Height. Default: 27", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,16 +777,16 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", "deposit-subtasks-list": "Landing list for subtasks deposited here:", "show-parent-in-minicard": "Show parent in minicard:", "description-on-minicard": "Description on minicard", - "cover-attachment-on-minicard": "Cover image on minicard", - "badge-attachment-on-minicard": "Count of attachments on minicard", - "card-sorting-by-number-on-minicard": "Card sorting by number on minicard", + "cover-attachment-on-minicard": "Imej depan kad mini", + "badge-attachment-on-minicard": "Bilangan lampiran pada kad mini", + "card-sorting-by-number-on-minicard": "Kad disusun mengikut nombor pada kad mini", "prefix-with-full-path": "Prefix with full path", "prefix-with-parent": "Prefix with parent", "subtext-with-full-path": "Subtext with full path", @@ -877,7 +899,7 @@ "r-items-list": "item1,item2,item3", "r-add-swimlane": "Add swimlane", "r-swimlane-name": "swimlane name", - "r-board-note": "Note: leave a field empty to match every possible value. ", + "r-board-note": "Nota: Tinggalkan ruang kosong untuk padankan setiap nilai yang mungkin.", "r-checklist-note": "Note: checklist's items have to be written as comma separated values.", "r-when-a-card-is-moved": "When a card is moved to another list", "r-set": "Set", @@ -908,10 +930,10 @@ "oidc-button-text": "Customize the OIDC button text", "default-authentication-method": "Default Authentication Method", "duplicate-board": "Duplicate Board", - "duplicate-board-confirm": "Are you sure you want to duplicate this board?", - "org-number": "The number of organizations is: ", - "team-number": "The number of teams is: ", - "people-number": "The number of people is: ", + "duplicate-board-confirm": "Anda pasti untuk menduplikasi papan ini?", + "org-number": "Jumlah Organisasi ialah:", + "team-number": "Jumlah kumpulan ialah:", + "people-number": "Jumlah individu ialah:", "swimlaneDeletePopup-title": "Delete Swimlane ?", "swimlane-delete-pop": "All actions will be removed from the activity feed and you won't be able to recover the swimlane. There is no undo.", "restore-all": "Restore all", @@ -979,7 +1001,7 @@ "delete-linked-card-before-this-card": "You can not delete this card before first deleting linked card that has", "delete-linked-cards-before-this-list": "You can not delete this list before first deleting linked cards that are pointing to cards in this list", "hide-checked-items": "Hide checked items", - "hide-finished-checklist": "Hide finished checklist", + "hide-finished-checklist": "Sembunyikan senarai semak yang telah selesai", "task": "Task", "create-task": "Create Task", "ok": "OK", @@ -987,7 +1009,7 @@ "teams": "Teams", "displayName": "Nama Paparan", "shortName": "Nama Ringkas", - "autoAddUsersWithDomainName": "Automatically add users with the domain name", + "autoAddUsersWithDomainName": "Tambah pengguna dengan nama domain ini secara lalai", "website": "Laman Sesawang", "person": "Person", "my-cards": "Kad Saya", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Saya", "dueCardsViewChange-choice-all": "Semua Pengguna", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "Tiada Kad Tamat Ditemui", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Maklumat", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ms.i18n.json b/imports/i18n/data/ms.i18n.json index 80514292e..966475e88 100644 --- a/imports/i18n/data/ms.i18n.json +++ b/imports/i18n/data/ms.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Semua Templat", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Buka", "board-view-gantt": "Gantt", "board-view-lists": "Senarai", - "bucket-example": "Contohnya \"Bucket List\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Batal", "card-archived": "Kad ini telah dipindahkan ke Arkib", "board-archived": "Papan ini telah dipindahkan ke Arkib", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Cipta", "createBoardPopup-title": "Cipta Papan", + "createTemplateContainerPopup-title": "Tambah Bekas Templat", "chooseBoardSourcePopup-title": "Import Papan", "createLabelPopup-title": "Cipta Label", "createCustomField": "Cipta ruangan", @@ -354,6 +369,10 @@ "custom-field-text": "Teks", "custom-fields": "Ruangan Khas", "date": "Tarikh", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Ditolak", "default-avatar": "Avatar Lalai", "delete": "Hapus", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Ubah Makluman", "editProfilePopup-title": "Ubah Profil", "email": "Emel", + "email-address": "Email Address", "email-enrollAccount-subject": "Satu akaun telah dicipta untuk anda pada __siteName__", "email-enrollAccount-text": "Salam Sejahtera __user__\nUntuk mula menggunakan servis, cuma perlu klik pautan di bawah\n\n__url__\n\nTerima kasih.", "email-fail": "Gagal menghantar emel", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Semua senarai, kad, label dan aktiviti akan dihapus dan anda tidak akan dapat pulihkan semula kandungan papan. Tiada undur semula", "boardDeletePopup-title": "Hapus Papan?", "delete-board": "Hapus papan", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "subtugas untuk __board__ papan", "default": "Lalai", "defaultdefault": "Lalai", @@ -755,7 +777,7 @@ "subtask-settings": "Tetapan Subtugas", "card-settings": "Tetapan Kad", "minicard-settings": "Tetapan kadmini", - "boardSubtaskSettingsPopup-title": "Tetapan Subtugas Papan", + "boardSubtaskSettingsPopup-title": "Tetapan Subtugas", "boardCardSettingsPopup-title": "Tetapan Kad", "boardMinicardSettingsPopup-title": "Tetapan kadmini", "deposit-subtasks-board": "Masukkan subtugas kepada papan ini:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Perincian", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Lengkap", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "daripada", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/nb.i18n.json b/imports/i18n/data/nb.i18n.json index 1b74fa6fe..4557e6542 100644 --- a/imports/i18n/data/nb.i18n.json +++ b/imports/i18n/data/nb.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "slettet kommentar %s", "activity-receivedDate": "redigert mottatt dato til %s av %s", "activity-startDate": "redigert startdato til %s av %s", + "allboards.starred": "Starred", + "allboards.templates": "Maler", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "redigert forfallsdato til %s av %s", "activity-endDate": "redigert sluttdato %s av %s", "add-attachment": "Legg til Vedlegg", @@ -190,7 +202,9 @@ "board-view-collapse": "Slå sammen", "board-view-gantt": "Gantt", "board-view-lists": "Lister", - "bucket-example": "Som 'Bucket List' for eksempel", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Avbryt", "card-archived": "Dette kortet er flyttet til Arkivet", "board-archived": "Denne tavlen er flyttet til Arkivet", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"Tittel\": \"Tittel første kort\", \"Beskrivelse\":\"Beskrivelse første kort\"}, {\"Tittel\":\"Tittel andre kort\",\"Beskrivelse\":\"Beskrivelse andre kort\"},{\"Tittel\":\"Tittel siste kort\",\"Beskrivelse\":\"Beskrivelse siste kort\"} ]", "create": "Opprett", "createBoardPopup-title": "Opprett Tavle", + "createTemplateContainerPopup-title": "Legg til Malgruppe", "chooseBoardSourcePopup-title": "Importer tavle", "createLabelPopup-title": "Opprett Etikett", "createCustomField": "Opprett Felt", @@ -354,6 +369,10 @@ "custom-field-text": "Tekst", "custom-fields": "Tilpassede felt", "date": "Dato", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Avvis", "default-avatar": "Standard avatar", "delete": "Slett", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Endre Varsel", "editProfilePopup-title": "Endre profil", "email": "E-post", + "email-address": "Email Address", "email-enrollAccount-subject": "En brukerkonto er opprettet for deg på __siteName__", "email-enrollAccount-text": "Hei __user__,\n\nFor å ta i bruk tjenesten, klikk på linken under.\n\n__url__\n\nTakk.", "email-fail": "Sending av epost feilet", @@ -748,6 +768,8 @@ "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?", "delete-board": "Slett Tavle", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Underoppgave for __board__ tavle", "default": "Standard", "defaultdefault": "Standard", @@ -755,7 +777,7 @@ "subtask-settings": "Innstillinger Underoppgave", "card-settings": "Innstillinger Kort", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Innstillinger Tavle Underoppgaver", + "boardSubtaskSettingsPopup-title": "Innstillinger Underoppgave", "boardCardSettingsPopup-title": "Innstillinger Kort", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Sett inn Underoppgave på Tavle:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Meg", "dueCardsViewChange-choice-all": "Alle Brukere", "dueCardsViewChange-choice-all-description": "Viser alle kort som ikke er ferdigstilt, med \"Forfallsdato\" fra tavler som brukeren har rettigheter til.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Brutte Kort", "board-title-not-found": "Tavle '%s' ikke funnet.", "swimlane-title-not-found": "Svømmebane '%s' ikke funnet.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Detaljer", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Gjennomført", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "av", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/nl-NL.i18n.json b/imports/i18n/data/nl-NL.i18n.json index b41d5cf1e..46eb730b3 100644 --- a/imports/i18n/data/nl-NL.i18n.json +++ b/imports/i18n/data/nl-NL.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "aantekening verwijderd %s", "activity-receivedDate": "ontvangst datum gewijzigd naar %s van %s", "activity-startDate": "start datum gewijzigd naar %s van %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "vervaldatum gewijzigd naar %s van %s", "activity-endDate": "einddatum gewijzigd naar %s van %s", "add-attachment": "Bijlage Toevoegen", @@ -190,7 +202,9 @@ "board-view-collapse": "Klap in", "board-view-gantt": "Gantt", "board-view-lists": "Lijsten", - "bucket-example": "Zoals bijvoorbeeld een \"Bucket List\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Annuleren", "card-archived": "Deze kaart is verplaatst naar Archief.", "board-archived": "Dit bord is verplaatst naar Archief.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Titel eerste kaart\", \"description\":\"Omschrijving eerste kaart\"}, {\"title\":\"Titel tweede kaart\",\"description\":\"Omschrijving tweede kaart\"},{\"title\":\"Titel laatste kaart\",\"description\":\"Omschrijving laatste kaart\"} ]", "create": "Aanmaken", "createBoardPopup-title": "Bord aanmaken", + "createTemplateContainerPopup-title": "Template Container Toevoegen", "chooseBoardSourcePopup-title": "Importeer bord", "createLabelPopup-title": "Label aanmaken", "createCustomField": "Veld aanmaken", @@ -354,6 +369,10 @@ "custom-field-text": "Tekst", "custom-fields": "Maatwerkvelden", "date": "Datum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Weigeren", "default-avatar": "Standaard avatar", "delete": "Verwijderen", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Wijzig notificatie", "editProfilePopup-title": "Wijzig profiel", "email": "E-mail", + "email-address": "Email Address", "email-enrollAccount-subject": "Er is een account voor je aangemaakt op __siteName__", "email-enrollAccount-text": "Hallo __user__,\n\nOm gebruik te maken van de online dienst, kan je op de volgende link klikken.\n\n__url__\n\nBedankt.", "email-fail": "E-mail verzenden is mislukt", @@ -748,6 +768,8 @@ "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?", "delete-board": "Verwijder bord", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtaken voor __board__ bord", "default": "Standaard", "defaultdefault": "Standaard", @@ -755,7 +777,7 @@ "subtask-settings": "Subtaak Instellingen", "card-settings": "Kaart Instellingen", "minicard-settings": "Minikaart Instellingen", - "boardSubtaskSettingsPopup-title": "Bord Subtaak Instellingen", + "boardSubtaskSettingsPopup-title": "Subtaak Instellingen", "boardCardSettingsPopup-title": "Kaart Instellingen", "boardMinicardSettingsPopup-title": "Minikaart Instellingen", "deposit-subtasks-board": "Plaats subtaken op dit bord:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Mij", "dueCardsViewChange-choice-all": "Alle gebruikers", "dueCardsViewChange-choice-all-description": "Toon incomplete kaarten met een *achterstallige* datum van borden waarvoor de gebruiker toegang heeft.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Defecte kaarten", "board-title-not-found": "Bord '%s' niet gevonden.", "swimlane-title-not-found": "Swimlane '%s' niet gevonden.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Afgewerkt", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "van", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/nl.i18n.json b/imports/i18n/data/nl.i18n.json index c243a8c0d..79b9a4b75 100644 --- a/imports/i18n/data/nl.i18n.json +++ b/imports/i18n/data/nl.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "aantekening verwijderd %s", "activity-receivedDate": "ontvangst datum gewijzigd naar %s van %s", "activity-startDate": "start datum gewijzigd naar %s van %s", + "allboards.starred": "Favorieten", + "allboards.templates": "Templates", + "allboards.remaining": "Resterend", + "allboards.workspaces": "Werkruimte", + "allboards.add-workspace": "Werkruimte toevoegen", + "allboards.add-workspace-prompt": "Werkruimtenaam", + "allboards.add-subworkspace": "Sub-werkruimte toevoegen", + "allboards.add-subworkspace-prompt": "Sub-werkruimtenaam", + "allboards.edit-workspace": "Wijzig werkruimte", + "allboards.edit-workspace-name": "Werkruimtenaam", + "allboards.edit-workspace-icon": "Werkruimteicoon (markdown)", + "multi-selection-active": "Vink de checkboxen om borden te selecteren", "activity-dueDate": "vervaldatum gewijzigd naar %s van %s", "activity-endDate": "einddatum gewijzigd naar %s van %s", "add-attachment": "Bijlage Toevoegen", @@ -190,7 +202,9 @@ "board-view-collapse": "Inklappen", "board-view-gantt": "Gantt", "board-view-lists": "Lijsten", - "bucket-example": "Zoals bijvoorbeeld een \"Bucket List\"", + "bucket-example": "Zoals bijvoorbeeld \"Bucketlist\"", + "calendar-previous-month-label": "Vorige Maand", + "calendar-next-month-label": "Volgende Maand", "cancel": "Annuleren", "card-archived": "Deze kaart is verplaatst naar Archief.", "board-archived": "Dit bord is verplaatst naar Archief.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Titel eerste kaart\", \"description\":\"Omschrijving eerste kaart\"}, {\"title\":\"Titel tweede kaart\",\"description\":\"Omschrijving tweede kaart\"},{\"title\":\"Titel laatste kaart\",\"description\":\"Omschrijving laatste kaart\"} ]", "create": "Aanmaken", "createBoardPopup-title": "Bord aanmaken", + "createTemplateContainerPopup-title": "Template Container Toevoegen", "chooseBoardSourcePopup-title": "Importeer bord", "createLabelPopup-title": "Label aanmaken", "createCustomField": "Veld aanmaken", @@ -354,6 +369,10 @@ "custom-field-text": "Tekst", "custom-fields": "Maatwerkvelden", "date": "Datum", + "date-format": "Datumformaat", + "date-format-yyyy-mm-dd": "JJJJ-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-JJJJ", + "date-format-mm-dd-yyyy": "MM-DD-JJJJ", "decline": "Weigeren", "default-avatar": "Standaard avatar", "delete": "Verwijderen", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Wijzig notificatie", "editProfilePopup-title": "Wijzig profiel", "email": "E-mail", + "email-address": "Emailadres", "email-enrollAccount-subject": "Er is een account voor je aangemaakt op __siteName__", "email-enrollAccount-text": "Hallo __user__,\n\nOm gebruik te maken van de online dienst, kan je op de volgende link klikken.\n\n__url__\n\nBedankt.", "email-fail": "E-mail verzenden is mislukt", @@ -631,9 +651,9 @@ "upload": "Upload", "upload-avatar": "Upload een avatar", "uploaded-avatar": "Avatar is geüpload", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "Bestanden uploaden", + "upload-failed": "Upload mislukt", + "upload-completed": "Upload geslaagd", "custom-top-left-corner-logo-image-url": "URL Voor Maatwerk Logo Afbeelding In Linker Bovenhoek", "custom-top-left-corner-logo-link-url": "URL Voor Maatwerk Logo Link In Linker Bovenhoek", "custom-top-left-corner-logo-height": "Hoogte Van Maatwerk Logo In Linker Bovenhoek. Default: 27", @@ -748,6 +768,8 @@ "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?", "delete-board": "Verwijder bord", + "delete-duplicate-lists": "Verwijder Dubbele Lijsten", + "delete-duplicate-lists-confirm": "Weet je het zeker? Alle dubbele lijsten die dezelfde naam hebben en geen kaarten bevatten worden verwijderd.", "default-subtasks-board": "Subtaken voor __board__ bord", "default": "Standaard", "defaultdefault": "Standaard", @@ -755,7 +777,7 @@ "subtask-settings": "Subtaak Instellingen", "card-settings": "Kaart Instellingen", "minicard-settings": "Minikaart Instellingen", - "boardSubtaskSettingsPopup-title": "Bord Subtaak Instellingen", + "boardSubtaskSettingsPopup-title": "Subtaak Instellingen", "boardCardSettingsPopup-title": "Kaart Instellingen", "boardMinicardSettingsPopup-title": "Minikaart Instellingen", "deposit-subtasks-board": "Plaats subtaken op dit bord:", @@ -914,7 +936,7 @@ "people-number": "Het aantal gebruikers is:", "swimlaneDeletePopup-title": "Swimlane verwijderen?", "swimlane-delete-pop": "Alle acties zullen verwijderd worden van de activiteiten feed en je kunt de swimlane niet terughalen. Er is geen herstelmogelijkheid.", - "restore-all": "Haal alles terug", + "restore-all": "Herstel alles", "delete-all": "Verwijder alles", "loading": "Laden, even geduld.", "previous_as": "laatste keer was", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Mij", "dueCardsViewChange-choice-all": "Alle gebruikers", "dueCardsViewChange-choice-all-description": "Toon incomplete kaarten met een *achterstallige* datum van borden waarvoor de gebruiker toegang heeft.", + "dueCards-noResults-title": "Geen Achterstallige Kaarten Gevonden", + "dueCards-noResults-description": "Je hebt nu geen kaarten met achterstallige datums.", "broken-cards": "Defecte kaarten", "board-title-not-found": "Bord '%s' niet gevonden.", "swimlane-title-not-found": "Swimlane '%s' niet gevonden.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "Gebruiker is actief - klik om te deactiveren", "admin-people-user-inactive": "Gebruiker is inactief - klik om te activeren", "accounts-lockout-all-users-unlocked": "Alle geblokkeerde gebruikers zijn ge-deblokkeerd", - "accounts-lockout-unlock-all": "Deblokkeer Alles" + "accounts-lockout-unlock-all": "Deblokkeer Alles", + "active-cron-jobs": "Actieve Geplande Taken", + "add-cron-job": "Voeg Geplande Taak Toe", + "add-cron-job-placeholder": "Geplande Taak toevoeg functionaliteit komt snel", + "attachment-storage-configuration": "Bijlage Opslag Configuratie", + "attachments-path": "Bijlagen Map", + "attachments-path-description": "Map waar bijlagen worden opgeslagen", + "avatars-path": "Avatars Path", + "avatars-path-description": "Map waar avatar bestanden worden opgeslagen", + "board-archive-failed": "Bord archiveren plannen mislukt", + "board-archive-scheduled": "Bord archiveren plannen gelukt", + "board-backup-failed": "Bord backup plannen mislukt", + "board-backup-scheduled": "Bord backup plannen gelukt", + "board-cleanup-failed": "Bord opschonen plannen mislukt", + "board-cleanup-scheduled": "Bord opschonen plannen gelukt", + "board-operations": "Bord Acties", + "cron-jobs": "Geplande Taken", + "cron-migrations": "Geplande Migraties", + "cron-job-delete-confirm": "Weet je zeker dat je deze geplande taak wilt verwijderen?", + "cron-job-delete-failed": "Geplande taak verwijderen mislukt", + "cron-job-deleted": "Geplande taak verwijderen gelukt", + "cron-job-pause-failed": "Geplande taak pauzeren mislukt", + "cron-job-paused": "Geplande taak pauzeren gelukt", + "filesystem-path-description": "Hoofdmap voor bestandsopslag", + "gridfs-enabled": "GridFS Ingeschakeld", + "gridfs-enabled-description": "Gebruik MongoDB GridFS voor bestandsopslag", + "migration-pause-failed": "Migraties pauzeren mislukt", + "migration-paused": "Migraties pauzeren gelukt", + "migration-progress": "Migratie Voortgang", + "migration-start-failed": "Migraties starten mislukt", + "migration-started": "Migraties starten gelukt", + "migration-status": "Migratie Status", + "migration-stop-confirm": "Weet je zeker dat je alle migraties wilt stoppen?", + "migration-stop-failed": "Migraties stoppen mislukt", + "migration-stopped": "Migraties stoppen gelukt", + "mongodb-gridfs-storage": "MongoDB GridFS Opslag", + "pause-all-migrations": "Alle Migraties Pauzeren", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key voor authenticatie", + "s3-access-key-placeholder": "Voer S3 access key in", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket naam voor bestandsopslag", + "s3-connection-failed": "S3 verbinding mislukt", + "s3-connection-success": "S3 verbinding gelukt", + "s3-enabled": "S3 Ingeschakeld", + "s3-enabled-description": "Gebruik AWS S3 of MinIO voor bestandsopslag", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (bv., s3.amazonaws.com of minio.example.com)", + "s3-minio-storage": "S3/MinIO Opslag", + "s3-port": "S3 Poort", + "s3-port-description": "S3 endpoint poort nummer", + "s3-region": "S3 Regio", + "s3-region-description": "AWS S3 regio (bv., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key voor authenticatie", + "s3-secret-key-placeholder": "Voer S3 secret key in", + "s3-secret-key-required": "S3 secret key is vereist", + "s3-settings-save-failed": "S3 instellingen opslaan mislukt", + "s3-settings-saved": "S3 instellingen opslaan gelukt", + "s3-ssl-enabled": "S3 SSL Ingeschakeld", + "s3-ssl-enabled-description": "Gebruik SSL/TLS voor S3 verbindingen", + "save-s3-settings": "S3 Instellingen Opslaan", + "schedule-board-archive": "Plan Bord Archiveren", + "schedule-board-backup": "Plan Bord Backup", + "schedule-board-cleanup": "Plan Bord Opschonen", + "scheduled-board-operations": "Geplande Bord Acties", + "start-all-migrations": "Start Alle Migraties", + "stop-all-migrations": "Stop Alle Migraties", + "test-s3-connection": "Test S3 Verbinding", + "writable-path": "Schrijfbare Map", + "writable-path-description": "Hoofdmap voor bestandsopslag", + "add-job": "Taak Toevoegen", + "attachment-migration": "Bijlage(n) Migratie", + "attachment-monitoring": "Bijlage(n) Monitoring", + "attachment-settings": "Bijlage(n) Instellingen", + "attachment-storage-settings": "Opslag Instellingen", + "automatic-migration": "Automatische Migratie", + "back-to-settings": "Terug naar Instellingen", + "board-id": "Bord ID", + "board-migration": "Bord Migratie", + "board-migrations": "Bord Migraties", + "card-show-lists-on-minicard": "Toon Lijsten op Minikaart", + "comprehensive-board-migration": "Uitgebreide Bord Migratie", + "comprehensive-board-migration-description": "Voert uitgebreide controles en reparaties uit voor bord data-integriteit, inclusief lijst sortering, kaart posities en swimlane-structuur.", + "delete-duplicate-empty-lists-migration": "Verwijder Dubbele Lege Lijsten", + "delete-duplicate-empty-lists-migration-description": "Verwijderd veilig lege dubbele lijsten. Verwijderd alleen lijsten die geen kaarten bevatten EN waar een andere lijst bestaat met dezelfde titel die wel kaarten bevat.", + "lost-cards": "Verloren Kaarten", + "lost-cards-list": "Herstelde Items", + "restore-lost-cards-migration": "Herstel Verloren Kaarten", + "restore-lost-cards-migration-description": "Vind en herstel kaarten en lijsten met missende swimlane-ID of list-ID. Hier wordt een 'Verloren Kaarten'-swimlane gemaakt om alles verloren items weer zichtbaar te maken.", + "restore-all-archived-migration": "Herstel Alles ui Archief", + "restore-all-archived-migration-description": "Herstel alle ge-archiveerde swimlanes, lijsten en kaarten. Hierbij worden automatisch de missende swimlane-ID of lijs-ID gerapareerd om de items weer zichtbaar te maken.", + "fix-missing-lists-migration": "Repareer Missende Lijsten", + "fix-missing-lists-migration-description": "Detecteer en repareer missende of corrupte lijsten in de bordstructuur.", + "fix-avatar-urls-migration": "Repareer Avatar URL's", + "fix-avatar-urls-migration-description": "Werkt de avatar URL's van de bord-leden bij zodat de juiste opslagmethode gebruikt wordt en het repareert defecte avatar verwijzingen.", + "fix-all-file-urls-migration": "Repareer alle bestand URL's", + "fix-all-file-urls-migration-description": "Werkt alle bestandsbijlagen URL's op dit bord bij naar de juiste opslagmethode en repareert defecte bestandsverwijzingen.", + "migration-needed": "Migratie Nodig", + "migration-complete": "Voltooid", + "migration-running": "In Uitvoering...", + "migration-successful": "Migratie succesvol uitgevoerd", + "migration-failed": "Migratie mislukt", + "migrations": "Migraties", + "migrations-admin-only": "Alleen bord-beherders kunnen migraties uitvoeren", + "migrations-description": "Voer data-integriteits controles en reparaties uit op dit bord. Elke migratie kan afzonderlijk uitgevoerd worden.", + "no-issues-found": "Geen problemen gevonden", + "run-migration": "Voer Migratie Uit", + "run-comprehensive-migration-confirm": "Dit voert een uitgebreide migratie uit en controleert en repareert de data-integriteit op dit bord. Dit kan even duren. Doorgaan?", + "run-delete-duplicate-empty-lists-migration-confirm": "Dit converteert eventuele gedeelde lijsten naar lijsten per swimlane waarna lege lijsten verwijderd worden die dubbel zijn met een lijst met dezelfde titel en wel kaarten bevatten. Alleen echt dubbele lege lijsten worden verwijderd. Doorgaan?", + "run-restore-lost-cards-migration-confirm": "Dit creëert een 'Verloren Kaarten' swimlane en hierin worden kaarten en lijsten hersteld met een missende swimlane-ID of lijst-ID. Dit heeft alleen gevolgen voor niet gearchiveerde items. Doorgaan?", + "run-restore-all-archived-migration-confirm": "Dit herstelt alle gearchiveerde swimlanes, lijsten en kaarten waardoor ze weer zichtbaar worden. Items met een missende ID zulle automatisch gerepareerd worden. Doorgaan?", + "run-fix-missing-lists-migration-confirm": "Dit detecteert en repareert missende of corrupte lijsten in de bord-structuur. Doorgaan?", + "run-fix-avatar-urls-migration-confirm": "Dit werkt alle avatar URL's van de bord-leden bij naar de juiste opslagmethode. Doorgaan?", + "run-fix-all-file-urls-migration-confirm": "dit werkt alle bestandsbijlagen URL's bij naar de juiste opslagmethode. Doorgaan?", + "restore-lost-cards-nothing-to-restore": "Geen verloren swinmlanes, lijsten of kaarten om te herstellen", + + "migration-progress-title": "Bord Migratie in Uitvoering", + "migration-progress-overall": "Algehele Voortgang", + "migration-progress-current-step": "Huidige Stap", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Wacht tot we jouw bord gemigreerd hebben naar de actuele structuur...", + + "step-analyze-board-structure": "Bordstructuur Analyseren", + "step-fix-orphaned-cards": "Repareer Verweesde Kaarten", + "step-convert-shared-lists": "Converteer Gedeelde Lijsten", + "step-ensure-per-swimlane-lists": "Maak Per-Swimlane Lijsten", + "step-validate-migration": "Valideer Migratie", + "step-fix-avatar-urls": "Repareer Avatar URL's", + "step-fix-attachment-urls": "Repareer Bijlage URL's", + "step-analyze-lists": "Analyseer Lijsten", + "step-create-missing-lists": "Maak Missende Lijsten", + "step-update-cards": "Werk Kaarten Bij", + "step-finalize": "Beëindig", + "step-delete-duplicate-empty-lists": "Verwijder Dubbele Lege Lijsten", + "step-ensure-lost-cards-swimlane": "Maak Verloren Kaarten Swimlane", + "step-restore-lists": "Herstel Lijsten", + "step-restore-cards": "Herstel Kaarten", + "step-restore-swimlanes": "Herstel Swimlanes", + "step-fix-missing-ids": "Herstel Missende ID's", + "step-scan-users": "Bord-leden avatars controleren", + "step-scan-files": "Bord bestandsbijlagen controleren", + "step-fix-file-urls": "Herstel bestand URL's", + "cleanup": "Opschonen", + "cleanup-old-jobs": "Schoon Oude Taken Op", + "completed": "Afgewerkt", + "conversion-info-text": "Deze conversie wordt eenmaal per bord uitgevoerd en verbeterd de prestaties. Je kunt het bord normaal blijven gebruiken.", + "converting-board": "Bord Converteren", + "converting-board-description": "Bordstructuur converteren voor verbeterde functionaliteit. Dit kan even duren.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Gebruik", + "current-action": "Huidige Actie", + "database-migration": "Database Migratie", + "database-migration-description": "Databasestructuur bijwerken voor verbeterde functionaliteit en prestaties. Dit kan enige minuten duren.", + "database-migrations": "Database Migraties", + "days-old": "Dagen Oud", + "duration": "Duur", + "errors": "Fouten", + "estimated-time-remaining": "Geschatte resterende tijd", + "every-1-day": "Elke dag", + "every-1-hour": "Elk uur", + "every-1-minute": "Elke minuut", + "every-10-minutes": "Elke 10 minuten", + "every-30-minutes": "Elke 30 minuten", + "every-5-minutes": "Elke 5 minuten", + "every-6-hours": "Elke 6 uur", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Bestandssysteem Bijlagen", + "filesystem-size": "Bestandssysteem Grootte", + "filesystem-storage": "Bestandssysteem Opslag", + "force-board-scan": "Forceer Bord Scan", + "gridfs-attachments": "GridFS Bijlagen", + "gridfs-size": "GridFS Grootte", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Verberg Lijst op Minikaart", + "idle-migration": "Inactieve Migratie", + "job-description": "Taak Beschrijving", + "job-details": "Taak Details", + "job-name": "Taak Naam", + "job-queue": "Taak Wachtrij", + "last-run": "Laatst Uitgevoerd", + "max-concurrent": "Max Concurrent", + "memory-usage": "Geheugen Gebruik", + "migrate-all-to-filesystem": "Migreer Alles naar Bestandssysteem", + "migrate-all-to-gridfs": "Migreer Alles naar GridFS", + "migrate-all-to-s3": "Migreer Alles naar S3", + "migrated-attachments": "Gemigreerde Bijlagen", + "migration-batch-size": "Batch Grootte", + "migration-batch-size-description": "Aantal te verwerken bijlagen in elke batch (1-100)", + "migration-cpu-threshold": "CPU Begrenzing (%)", + "migration-cpu-threshold-description": "Pauzeer migratie als CPU gebruik dit percentage overstijgt (10-90)", + "migration-delay-ms": "Wachttijd (ms)", + "migration-delay-ms-description": "Wachttijd tussen batches in milliseconden (100-10000)", + "migration-detector": "Migratie Detector", + "migration-info-text": "Databasemigraties worden eenmalig uitgevoerd en verbeteren de systeemprestaties. Dit proces gaat in de achtergrond door, zelfs als je je browser afsluit.", + "migration-log": "Migratie Log", + "migration-markers": "Migratie Stappen", + "migration-resume-failed": "Migratie hervatten mislukt", + "migration-resumed": "Migratie hervat", + "migration-steps": "Migratie Stappen", + "migration-warning-text": "Sluit je browser niet af tijdens de migratie. Het proces gaat in de achtergrond wel door maar duurt dan mogelijk langer.", + "monitoring-export-failed": "Export van monitoring data mislukt", + "monitoring-refresh-failed": "Bijwerken van monitoring data mislukt", + "next": "Volgende", + "next-run": "Volgende Uitvoering", + "of": "van", + "operation-type": "Actie Type", + "overall-progress": "Algehele Voortgang", + "page": "Pagina", + "pause-migration": "Pauzeer Migratie", + "previous": "Vorige", + "refresh": "Bijwerken", + "refresh-monitoring": "Monitoring Bijwerken", + "remaining-attachments": "Resterende Bijlagen", + "resume-migration": "Hervat Migratie", + "run-once": "Eenmaal uitvoeren", + "s3-attachments": "S3 Bijlagen", + "s3-size": "S3 Grootte", + "s3-storage": "S3", + "scanning-status": "Scan Status", + "schedule": "Plannen", + "search-boards-or-operations": "Zoek borden of acties...", + "show-list-on-minicard": "Toon Lijst op Minikaart", + "showing": "Tonen", + "start-test-operation": "Start Test Actie", + "start-time": "Starttijd", + "step-progress": "Stap Voortgang", + "stop-migration": "Stop Migratie", + "storage-distribution": "Opslag Verdeling", + "system-resources": "Systeem Bronnen", + "total-attachments": "Aantal Bijlagen", + "total-operations": "Aantal Acties", + "total-size": "Totale Grootte", + "unmigrated-boards": "Niet Gemigreerde Borden", + "weight": "Gewicht", + "idle": "Inactief", + "complete": "Voltooid", + "cron": "Planning" } diff --git a/imports/i18n/data/oc.i18n.json b/imports/i18n/data/oc.i18n.json index bea6e0c26..9c3543796 100644 --- a/imports/i18n/data/oc.i18n.json +++ b/imports/i18n/data/oc.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Modèls", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Apondre una pèça joncha", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Tièras", - "bucket-example": "Coma \"Tota la tièra\" per exemple", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Tornar", "card-archived": "Aquesta carta es desplaçada dins Archius.", "board-archived": "Aqueste tablèu esdesplaçat dins Archius.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Títol de la primièra carta\", \"description\":\"Descripcion de la primièra carta\"}, {\"title\":\"Títol de la segonda carta\",\"description\":\"Descripcion de la segonda carta\"},{\"title\":\"Títol de la darrièra carta\",\"description\":\"Descripcion de la darrièra carta\"} ]", "create": "Crear", "createBoardPopup-title": "Crear un tablèu", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importar un tablèu", "createLabelPopup-title": "Crear una etiqueta", "createCustomField": "Crear un camp", @@ -354,6 +369,10 @@ "custom-field-text": "Tèxte", "custom-fields": "Camps personalizats", "date": "Data", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Refusar", "default-avatar": "Fòto per defaut", "delete": "Suprimir", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Modificar la notificacion", "editProfilePopup-title": "Modificar lo perfil", "email": "Corrièl", + "email-address": "Email Address", "email-enrollAccount-subject": "Vòstre compte es ara activat pel sit __siteName__", "email-enrollAccount-text": "Adieu __user__,\n\nPer comença d'utilizar lo servici, vos cal clicar sul ligam.\n\n__url__\n\nMercé.", "email-fail": "Pas possible de mandar lo corrièl", @@ -748,6 +768,8 @@ "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 ?", "delete-board": "Tablèu suprimit", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/or_IN.i18n.json b/imports/i18n/data/or_IN.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/or_IN.i18n.json +++ b/imports/i18n/data/or_IN.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/pa.i18n.json b/imports/i18n/data/pa.i18n.json index 04a11c665..b6aac02e5 100644 --- a/imports/i18n/data/pa.i18n.json +++ b/imports/i18n/data/pa.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/pl-PL.i18n.json b/imports/i18n/data/pl-PL.i18n.json index 04fd6a802..c7ea811a7 100644 --- a/imports/i18n/data/pl-PL.i18n.json +++ b/imports/i18n/data/pl-PL.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "usunął komentarz %s", "activity-receivedDate": "zmienił datę otrzymania na %s z %s", "activity-startDate": "zmienił datę rozpoczęcia na %s z %s", + "allboards.starred": "Starred", + "allboards.templates": "Szablony", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "zmienił datę wykonania na %s z %s", "activity-endDate": "zmienił datę zakończenia na %s z %s", "add-attachment": "Dodaj załącznik", @@ -190,7 +202,9 @@ "board-view-collapse": "Zwiń", "board-view-gantt": "Wykres Gantta", "board-view-lists": "Listy", - "bucket-example": "Tak jak na przykład \"lista kubełkowa\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Anuluj", "card-archived": "Ta karta została przeniesiona do Archiwum.", "board-archived": "Ta tablica została przeniesiona do Archiwum.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Tytuł pierwszej karty\", \"description\":\"Opis pierwszej karty\"}, {\"title\":\"Tytuł drugiej karty\",\"description\":\"Opis drugiej karty\"},{\"title\":\"Tytuł ostatniej karty\",\"description\":\"Opis ostatniej karty\"} ]", "create": "Utwórz", "createBoardPopup-title": "Utwórz tablicę", + "createTemplateContainerPopup-title": "Dodaj Kontener Szablonów", "chooseBoardSourcePopup-title": "Import tablicy", "createLabelPopup-title": "Utwórz etykietę", "createCustomField": "Utwórz pole", @@ -354,6 +369,10 @@ "custom-field-text": "Tekst", "custom-fields": "Niestandardowe pola", "date": "Data", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Odrzuć", "default-avatar": "Domyślny avatar", "delete": "Usuń", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Zmień tryb powiadamiania", "editProfilePopup-title": "Edytuj profil", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Konto zostało utworzone na __siteName__", "email-enrollAccount-text": "Witaj __user__,\nAby zacząć korzystać z serwisu, kliknij w link poniżej.\n__url__\nDzięki.", "email-fail": "Wysyłanie emaila nie powiodło się.", @@ -748,6 +768,8 @@ "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ę?", "delete-board": "Usuń tablicę", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Podzadania dla tablicy __board__", "default": "Domyślny", "defaultdefault": "Domyślny", @@ -755,7 +777,7 @@ "subtask-settings": "Ustawienia podzadań", "card-settings": "Ustawienia kart", "minicard-settings": "Ustawienia miniatur kart", - "boardSubtaskSettingsPopup-title": "Ustawienia tablicy podzadań", + "boardSubtaskSettingsPopup-title": "Ustawienia podzadań", "boardCardSettingsPopup-title": "Ustawienia kart", "boardMinicardSettingsPopup-title": "Ustawienia miniatur kart", "deposit-subtasks-board": "Twórz podzadania na tablicy:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Moje", "dueCardsViewChange-choice-all": "Wszystkich użytkowników", "dueCardsViewChange-choice-all-description": "Wyświetla wszystkie nieukończone karty z ustawioną datą wykonania ze wszystkich tablic, do których użytkownik ma dostęp.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Karty wadliwe", "board-title-not-found": "Nie znaleziono tablicy '%s'.", "swimlane-title-not-found": "Nie znaleziono ścieżki '%s'.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Szczegóły", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "ukończona", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "z", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/pl.i18n.json b/imports/i18n/data/pl.i18n.json index 7e3d12f26..c01e9746d 100644 --- a/imports/i18n/data/pl.i18n.json +++ b/imports/i18n/data/pl.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "usunięto komentarz %s", "activity-receivedDate": "zmienił datę otrzymania na %s z %s", "activity-startDate": "zmienił datę rozpoczęcia na %s z %s", + "allboards.starred": "Starred", + "allboards.templates": "Szablony", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "zmienił datę wykonania na %s z %s", "activity-endDate": "zmienił datę zakończenia na %s z %s", "add-attachment": "Dodaj załącznik", @@ -190,7 +202,9 @@ "board-view-collapse": "Zwiń", "board-view-gantt": "Wykres Gantta", "board-view-lists": "Listy", - "bucket-example": "Tak jak na przykład \"lista kubełkowa\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Anuluj", "card-archived": "Ta karta została przeniesiona do Archiwum.", "board-archived": "Ta tablica została przeniesiona do Archiwum.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Tytuł pierwszej karty\", \"description\":\"Opis pierwszej karty\"}, {\"title\":\"Tytuł drugiej karty\",\"description\":\"Opis drugiej karty\"},{\"title\":\"Tytuł ostatniej karty\",\"description\":\"Opis ostatniej karty\"} ]", "create": "Utwórz", "createBoardPopup-title": "Utwórz tablicę", + "createTemplateContainerPopup-title": "Dodaj Kontener Szablonów", "chooseBoardSourcePopup-title": "Import tablicy", "createLabelPopup-title": "Utwórz etykietę", "createCustomField": "Utwórz pole", @@ -354,6 +369,10 @@ "custom-field-text": "Tekst", "custom-fields": "Niestandardowe pola", "date": "Data", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Odrzuć", "default-avatar": "Domyślny avatar", "delete": "Usuń", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Zmień tryb powiadamiania", "editProfilePopup-title": "Edytuj profil", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Konto zostało utworzone na __siteName__", "email-enrollAccount-text": "Witaj __user__,\nAby zacząć korzystać z serwisu, kliknij w link poniżej.\n__url__\nDzięki.", "email-fail": "Wysyłanie emaila nie powiodło się.", @@ -748,6 +768,8 @@ "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ę?", "delete-board": "Usuń tablicę", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Podzadania dla tablicy __board__", "default": "Domyślny", "defaultdefault": "Domyślny", @@ -755,7 +777,7 @@ "subtask-settings": "Ustawienia podzadań", "card-settings": "Ustawienia kart", "minicard-settings": "Ustawienia miniatur kart", - "boardSubtaskSettingsPopup-title": "Ustawienia tablicy podzadań", + "boardSubtaskSettingsPopup-title": "Ustawienia podzadań", "boardCardSettingsPopup-title": "Ustawienia kart", "boardMinicardSettingsPopup-title": "Ustawienia miniatur kart", "deposit-subtasks-board": "Twórz podzadania na tablicy:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Moje", "dueCardsViewChange-choice-all": "Wszystkich użytkowników", "dueCardsViewChange-choice-all-description": "Wyświetla wszystkie nieukończone karty z ustawioną datą wykonania ze wszystkich tablic, do których użytkownik ma dostęp.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Karty wadliwe", "board-title-not-found": "Nie znaleziono tablicy '%s'.", "swimlane-title-not-found": "Nie znaleziono ścieżki '%s'.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Szczegóły", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "ukończona", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "z", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/pt-BR.i18n.json b/imports/i18n/data/pt-BR.i18n.json index 06d076ac7..1a44664bb 100644 --- a/imports/i18n/data/pt-BR.i18n.json +++ b/imports/i18n/data/pt-BR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "comentário excluído %s", "activity-receivedDate": "editou recebido para %s de %s", "activity-startDate": "editou data início para %s de %s", + "allboards.starred": "Favoritado", + "allboards.templates": "Modelos", + "allboards.remaining": "Restante", + "allboards.workspaces": "Áreas de trabalho", + "allboards.add-workspace": "Adicionar Área de trabalho", + "allboards.add-workspace-prompt": "Nome da Área de trabalho", + "allboards.add-subworkspace": "Adicionar Subárea de trabalho", + "allboards.add-subworkspace-prompt": "Nome da Subárea de trabalho", + "allboards.edit-workspace": "Editar Área de trabalho", + "allboards.edit-workspace-name": "Nome da Área de trabalho", + "allboards.edit-workspace-icon": "Ícone da Área de trabalho (markdown)", + "multi-selection-active": "Clique nas caixas de seleção para selecionar os quadros", "activity-dueDate": "editou prazo final para %s de %s", "activity-endDate": "editou concluído para %s de %s", "add-attachment": "Adicionar Anexos", @@ -190,7 +202,9 @@ "board-view-collapse": "Expandir", "board-view-gantt": "Gantt", "board-view-lists": "Listas", - "bucket-example": "\"Bucket List\", por exemplo", + "bucket-example": "Como \"Lista de Desejos\", por exemplo", + "calendar-previous-month-label": "Mês Anterior", + "calendar-next-month-label": "Próximo Mês", "cancel": "Cancelar", "card-archived": "Este cartão está Arquivado.", "board-archived": "Este quadro está Arquivado.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Título do primeiro cartão\", \"description\":\"Descrição do primeiro cartão\"}, {\"title\":\"Título do segundo cartão\",\"description\":\"Descrição do segundo cartão\"},{\"title\":\"Título do último cartão\",\"description\":\"Descrição do último cartão\"} ]", "create": "Criar", "createBoardPopup-title": "Criar Quadro", + "createTemplateContainerPopup-title": "Adicionar Contêiner de Modelo", "chooseBoardSourcePopup-title": "Importar quadro", "createLabelPopup-title": "Criar Etiqueta", "createCustomField": "Criar campo", @@ -354,6 +369,10 @@ "custom-field-text": "Texto", "custom-fields": "Campos customizados", "date": "Data", + "date-format": "Formato da Data", + "date-format-yyyy-mm-dd": "AAAA-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-AAAA", + "date-format-mm-dd-yyyy": "MM-DD-AAAA", "decline": "Rejeitar", "default-avatar": "Avatar padrão", "delete": "Excluir", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editar Notificações", "editProfilePopup-title": "Editar Perfil", "email": "E-mail", + "email-address": "Endereço de e-mail", "email-enrollAccount-subject": "Uma conta foi criada para você em __siteName__", "email-enrollAccount-text": "Olá __user__\npara iniciar utilizando o serviço basta clicar no link abaixo.\n__url__\nMuito Obrigado.", "email-fail": "Falhou ao enviar e-mail", @@ -393,7 +413,7 @@ "email-verifyEmail-subject": "Verifique seu endereço de e-mail em __siteName__", "email-verifyEmail-text": "Olá __user__\nPara verificar sua conta de e-mail, clique no link abaixo.\n__url__\nObrigado.", "enable-vertical-scrollbars": "Habilitar rolagem de tela vertical", - "enable-wip-limit": "Ativar Limite WIP", + "enable-wip-limit": "Habilitar Limite WIP", "error-board-doesNotExist": "Este quadro não existe", "error-board-notAdmin": "Você precisa ser administrador desse quadro para fazer isto", "error-board-notAMember": "Você precisa ser um membro desse quadro para fazer isto", @@ -631,9 +651,9 @@ "upload": "Carregar", "upload-avatar": "Carregar um avatar", "uploaded-avatar": "Avatar carregado", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "Carregando arquivos", + "upload-failed": "Carregamento falhou", + "upload-completed": "Carregamento concluído", "custom-top-left-corner-logo-image-url": "URL da imagem do logo customizado do canto superior esquerdo", "custom-top-left-corner-logo-link-url": "URL do link do logo customizado do canto superior esquerdo", "custom-top-left-corner-logo-height": "Altura da imagem do logo customizado do canto superior esquerdo. Padrão: 27", @@ -748,6 +768,8 @@ "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?", "delete-board": "Excluir quadro", + "delete-duplicate-lists": "Excluir Listas Duplicadas", + "delete-duplicate-lists-confirm": "Você tem certeza? Isso vai apagar todas as litas duplicadas que possuem o mesmo nome e que não possuem cartões", "default-subtasks-board": "Subtarefas para quadro __board__", "default": "Padrão", "defaultdefault": "Padrão", @@ -755,7 +777,7 @@ "subtask-settings": "Configurações de subtarefas", "card-settings": "Configurações do Cartão", "minicard-settings": "Configurações do Mini cartão", - "boardSubtaskSettingsPopup-title": "Configurações das subtarefas do quadro", + "boardSubtaskSettingsPopup-title": "Configurações de subtarefas", "boardCardSettingsPopup-title": "Configurações do Cartão", "boardMinicardSettingsPopup-title": "Configurações do Mini cartão", "deposit-subtasks-board": "Inserir subtarefas a este quadro:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Eu", "dueCardsViewChange-choice-all": "Todos os usuários", "dueCardsViewChange-choice-all-description": "Mostrar todos os cartões incompletos com *Prazo Final* nos quadros em que o usuário tem permissão", + "dueCards-noResults-title": "Sem Cartões com prazo final", + "dueCards-noResults-description": "Você não possui cartões com prazo final neste momento", "broken-cards": "Cartões quebrados", "board-title-not-found": "Quadro '%s' não encontrado.", "swimlane-title-not-found": "Raia '%s' não encontrada.", @@ -1019,7 +1043,7 @@ "comment-not-found": "Cartões com comentários contendo o texto '%s' não encontrado.", "org-name-not-found": "Organização '%s' não encontrada.", "team-name-not-found": "Time '%s' não encontrado.", - "globalSearch-title": "Pesquisar em todos os quadros", + "globalSearch-title": "Buscar em todos os quadros", "no-cards-found": "Nenhum cartão encontrado", "one-card-found": "Um cartão encontrado", "n-cards-found": "%s cartões encontrados", @@ -1116,7 +1140,7 @@ "globalSearch-instructions-notes-3": "Operadores de diferenciação são *AND*, ou seja, to tipo \"E. Apenas cartões que correspondam a todos os operadores de diferenciação são retornados. `__operator_list__:Available __operator_label__:red` retorna apenas os cartões na lista *Available* com uma etiqueta *red*.", "globalSearch-instructions-notes-3-2": "Dias podem ser especificados como um inteiro positivo ou negativo ou usando `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` ou `__predicate_year__` para o período atual.", "globalSearch-instructions-notes-4": "Textos de busca não distinguem maiúsculas e minúsculas", - "globalSearch-instructions-notes-5": "Por padrão, cartões arquivados não são pesquisados.", + "globalSearch-instructions-notes-5": "Por padrão, cartões arquivados não são buscados.", "link-to-search": "Link para esta busca", "excel-font": "Arial", "number": "Número", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "Usuário está ativo - clique para desativá-lo", "admin-people-user-inactive": "Usuário está inativo - clique para ativá-lo", "accounts-lockout-all-users-unlocked": "Todos os usuários bloqueados foram desbloqueados", - "accounts-lockout-unlock-all": "Desbloquear Todos" + "accounts-lockout-unlock-all": "Desbloquear Todos", + "active-cron-jobs": "Trabalhos agendados ativos", + "add-cron-job": "Adicionar trabalhos agendados", + "add-cron-job-placeholder": "Funcionalidade para Adicionar Trabalhos Agendados virá em breve", + "attachment-storage-configuration": "Configuração de armazenamento de anexos", + "attachments-path": "Caminho dos Anexos", + "attachments-path-description": "Caminho onde os arquivos de anexos estão armazenados", + "avatars-path": "Caminho dos Avatares", + "avatars-path-description": "Caminho onde arquivos de avatar estão armazenados", + "board-archive-failed": "Falha ao agendar arquivamento de quadro", + "board-archive-scheduled": "Arquivamento de quadro agendado com sucesso", + "board-backup-failed": "Falha ao agendar backup de quadro", + "board-backup-scheduled": "Backup de quadro agendado com sucesso", + "board-cleanup-failed": "Falha ao agendar limpeza de quadro", + "board-cleanup-scheduled": "Limpeza de quadro agendada com sucesso", + "board-operations": "Operações de Quadro", + "cron-jobs": "Trabalhos Agendados", + "cron-migrations": "Migrações Agendadas", + "cron-job-delete-confirm": "Você tem certeza que deseja excluir este trabalho agendado?", + "cron-job-delete-failed": "Falha ao excluir trabalho agendado", + "cron-job-deleted": "Trabalho agendado excluído com sucesso", + "cron-job-pause-failed": "Falha ao parar trabalho agendado", + "cron-job-paused": "Agendamento de trabalho parado com sucesso", + "filesystem-path-description": "Caminho base para o armazenamento de arquivos", + "gridfs-enabled": "GridFS Habilitado", + "gridfs-enabled-description": "Use MongoDB GridFS para armazenamento de arquivos", + "migration-pause-failed": "Falha ao parar migrações", + "migration-paused": "Migrações paradas com sucesso", + "migration-progress": "Progresso das Migrações", + "migration-start-failed": "Falha ao iniciar migrações", + "migration-started": "Migrações iniciadas com sucesso", + "migration-status": "Status das Migrações", + "migration-stop-confirm": "Você tem certeza que deseja parar todas as migrações?", + "migration-stop-failed": "Falha ao parar migrações", + "migration-stopped": "Migrações paradas com sucesso", + "mongodb-gridfs-storage": "Armazenamento MongoDB GridFS", + "pause-all-migrations": "Parar Todas Migrações", + "s3-access-key": "Chave de Acesso S3", + "s3-access-key-description": "Chaves de acesso do AWS S3 para autenticação", + "s3-access-key-placeholder": "Insira as chaves de acesso do S3", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "Nome do S3 Bucket para armazenar arquivos", + "s3-connection-failed": "Falha ao conectar ao S3", + "s3-connection-success": "S3 conectado com sucesso", + "s3-enabled": "S3 Habilitado", + "s3-enabled-description": "Use AWS S3 ou MinIO para armazenamento de arquivos", + "s3-endpoint": "Dispositivo S3", + "s3-endpoint-description": "URL do dispositivo S3 (por exemplo: s3.amazonaws.com ou minio.example.com)", + "s3-minio-storage": "Armazenamento S3/MinIO", + "s3-port": "Porta do S3", + "s3-port-description": "Número da Porta do dispositivo S3", + "s3-region": "Região do S3", + "s3-region-description": "Região do AWS S3 (por exemplo: us-east-1)", + "s3-secret-key": "Chave secreta do S3", + "s3-secret-key-description": "Chave secreta do AWS S3 para autenticação", + "s3-secret-key-placeholder": "Insira a chave secreta do S3", + "s3-secret-key-required": "Chave secreta do S3 é requerida", + "s3-settings-save-failed": "Falha ao salvar configurações do S3", + "s3-settings-saved": "Configurações do S3 salvas com sucesso", + "s3-ssl-enabled": "S3 SSL Habilitado", + "s3-ssl-enabled-description": "Usar SSL/TLS para conexões do S3", + "save-s3-settings": "Salvar Configurações do S3", + "schedule-board-archive": "Agendar Arquivamento de Quadro", + "schedule-board-backup": "Agendar Backup de Quadro", + "schedule-board-cleanup": "Agendar Limpeza de Quadro", + "scheduled-board-operations": "Agendar Operações de Quadro", + "start-all-migrations": "Iniciar Todas as Migrações", + "stop-all-migrations": "Parar Todas as Migrações", + "test-s3-connection": "Testar Conexão com S3", + "writable-path": "Caminho gravável", + "writable-path-description": "Caminho do diretório base para armazenamento de arquivos", + "add-job": "Adicionar Trabalho", + "attachment-migration": "Migração de Anexo", + "attachment-monitoring": "Monitoramento de Anexo", + "attachment-settings": "Configurações de Anexo", + "attachment-storage-settings": "Configurações de Armazenamento", + "automatic-migration": "Migração Automática", + "back-to-settings": "Voltar às Configurações", + "board-id": "ID do Quadro", + "board-migration": "Migração de Quadro", + "board-migrations": "Migração de Quadros", + "card-show-lists-on-minicard": "Mostrar Listas no Mini cartão", + "comprehensive-board-migration": "Migração de Quadros abrangente", + "comprehensive-board-migration-description": "Realiza verificações e correções abrangentes para a integridade dos dados do quadro, incluindo a ordem da lista, as posições dos cartões e a estrutura das raias.", + "delete-duplicate-empty-lists-migration": "Apagar Listas Vazias Duplicadas", + "delete-duplicate-empty-lists-migration-description": "Exclui com segurança listas duplicadas vazias. Remove apenas listas que não contêm cartões E que possuem outra lista com o mesmo título que contém cartões.", + "lost-cards": "Cartões Perdidos", + "lost-cards-list": "Itens Recuperados", + "restore-lost-cards-migration": "Recuperar Cartões Perdidos", + "restore-lost-cards-migration-description": "Encontra e restaura cartões e listas com ID de raia ou ID de lista ausentes. Cria uma raia \"Cartões Perdidos\" para tornar todos os itens perdidos visíveis novamente.", + "restore-all-archived-migration": "Recuperar Todos Arquivados", + "restore-all-archived-migration-description": "Restaura todas as raias, listas e cartões arquivados. Corrige automaticamente qualquer ID de raia ou ID de lista ausente para tornar os itens visíveis.", + "fix-missing-lists-migration": "Corrigir Listas Ausentes", + "fix-missing-lists-migration-description": "Detecta e repara listas ausentes ou corrompidas na estrutura do quadro.", + "fix-avatar-urls-migration": "Corrigir URLs de Avatar", + "fix-avatar-urls-migration-description": "Atualiza os URLs dos avatares dos membros do quadro para que utilizem o backend de armazenamento correto e corrige referências de avatar quebradas.", + "fix-all-file-urls-migration": "Corrigir todas URLs de arquivos", + "fix-all-file-urls-migration-description": "Atualiza todas URLs de arquivos de anexo neste quadro para usar o backend de armazenamento correto e corrige referências de arquivos quebradas.", + "migration-needed": "Migração necessária", + "migration-complete": "Concluído", + "migration-running": "Executando...", + "migration-successful": "Migração concluída com sucesso.", + "migration-failed": "A migração falhou", + "migrations": "Migrações", + "migrations-admin-only": "Somente os administradores do quadro podem executar migrações.", + "migrations-description": "Execute verificações de integridade de dados e reparos para este quadro. Cada migração pode ser executada individualmente.", + "no-issues-found": "Nenhum problema encontrado", + "run-migration": "Executar Migração", + "run-comprehensive-migration-confirm": "Isso realizará uma migração completa para verificar e corrigir a integridade dos dados do quadro. Isso pode levar alguns instantes. Continuar?", + "run-delete-duplicate-empty-lists-migration-confirm": "Primeiro, isso converterá todas as listas compartilhadas em listas por raia e, em seguida, excluirá as listas vazias que contêm listas duplicadas com o mesmo título e que possuem cartões. Somente as listas vazias realmente redundantes serão removidas. Continuar?", + "run-restore-lost-cards-migration-confirm": "Isso criará uma raia \"Cartões Perdidos\" e restaurará todos os cartões e listas com ID de raia ou ID de lista ausentes. Isso afeta apenas itens não arquivados. Continuar?", + "run-restore-all-archived-migration-confirm": "Isso restaurará TODAS as raias, listas e cartões arquivados, tornando-os visíveis novamente. Quaisquer itens com IDs ausentes serão corrigidos automaticamente. Esta ação não pode ser desfeita facilmente. Continuar?", + "run-fix-missing-lists-migration-confirm": "Isso detectará e corrigirá listas ausentes ou corrompidas na estrutura do quadro. Continuar?", + "run-fix-avatar-urls-migration-confirm": "Isso atualizará as URLs dos avatares dos membros do quadro para usar o backend de armazenamento correto. Continuar?", + "run-fix-all-file-urls-migration-confirm": "Isso atualizará todas URLs de arquivos de anexos neste quadro para usar o servidor de armazenamento correto. Continuar?", + "restore-lost-cards-nothing-to-restore": "Sem raias, listas ou cartões perdidos para restaurar.", + + "migration-progress-title": "Migração do Quadro em Andamento", + "migration-progress-overall": "Progresso Geral", + "migration-progress-current-step": "Etapa Atual", + "migration-progress-status": "Status", + "migration-progress-details": "Detalhes", + "migration-progress-note": "Aguarde enquanto migramos seu quadro para a estrutura mais recente...", + + "step-analyze-board-structure": "Analisar a Estrutura do Quadro", + "step-fix-orphaned-cards": "Corrigir Cartões Órfãos", + "step-convert-shared-lists": "Converter Listas Compartilhadas", + "step-ensure-per-swimlane-lists": "Garantir listas por raia", + "step-validate-migration": "Validar Migração", + "step-fix-avatar-urls": "Corrigir URLs de Avatar", + "step-fix-attachment-urls": "Corrigir URLs de anexos", + "step-analyze-lists": "Analisar Listas", + "step-create-missing-lists": "Criar Listas Faltantes", + "step-update-cards": "Atualizar Cartões", + "step-finalize": "Finalizar", + "step-delete-duplicate-empty-lists": "Apagar Listas Vazias Duplicadas", + "step-ensure-lost-cards-swimlane": "Garantir a Raia dos Cartões Perdidos", + "step-restore-lists": "Restaurar Listas", + "step-restore-cards": "Restaurar Cartões", + "step-restore-swimlanes": "Restaurar Raias", + "step-fix-missing-ids": "Corrigir IDs ausentes", + "step-scan-users": "Verificando os avatares dos membros do quadro", + "step-scan-files": "Verificando arquivos de anexos do quadro", + "step-fix-file-urls": "Corrigindo URLs de arquivos", + "cleanup": "Limpeza", + "cleanup-old-jobs": "Limpar Trabalhos Antigos", + "completed": "Completado", + "conversion-info-text": "Esta conversão é realizada uma vez por quadro e melhora o desempenho. Você pode continuar usando o quadro normalmente.", + "converting-board": "Convertendo Quadro", + "converting-board-description": "Convertendo estrutura do quadro para melhorar a funcionalidade. Isto pode levar alguns instantes.", + "cpu-cores": "Núcleos de CPU", + "cpu-usage": "Uso de CPU", + "current-action": "Ação Atual", + "database-migration": "Migração de Banco de Dados", + "database-migration-description": "Atualizando estrutura de banco de dados para melhorar a funcionalidade e o desempenho. Este processo pode levar vários minutos.", + "database-migrations": "Migrações de Banco de Dados", + "days-old": "Dias de Vida", + "duration": "Duração", + "errors": "Erros", + "estimated-time-remaining": "Tempo restante estimado", + "every-1-day": "A cada 1 dia", + "every-1-hour": "A cada 1 hora", + "every-1-minute": "A cada 1 minuto", + "every-10-minutes": "A cada 10 minutos", + "every-30-minutes": "A cada 30 minutos", + "every-5-minutes": "A cada 5 minutos", + "every-6-hours": "A cada 6 horas", + "export-monitoring": "Exportar Monitoramento", + "filesystem-attachments": "Anexos do Sistema de Arquivos", + "filesystem-size": "Tamanho do Sistema de Arquivos", + "filesystem-storage": "Armazenamento do Sistema de Arquivos", + "force-board-scan": "Forçar Escaneamento do Quadro", + "gridfs-attachments": "Anexos do GridFS", + "gridfs-size": "Tamanho do GridFS", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Esconder Lista no Mini cartão", + "idle-migration": "Migração Parada", + "job-description": "Descrição do Trabalho", + "job-details": "Detalhes do Trabalho", + "job-name": "Nome do Trabalho", + "job-queue": "Fila de Trabalhos", + "last-run": "Última Execução", + "max-concurrent": "Concorrência Máxima", + "memory-usage": "Uso de memória", + "migrate-all-to-filesystem": "Migrar Todo o Sistema de Arquivos", + "migrate-all-to-gridfs": "Migrar Todo o GridFS", + "migrate-all-to-s3": "Migrar Todo o S3", + "migrated-attachments": "Anexos Migrados", + "migration-batch-size": "Tamanho do Lote", + "migration-batch-size-description": "Número de anexos a processar em cada lote (1-100)", + "migration-cpu-threshold": "Limite de CPU (%)", + "migration-cpu-threshold-description": "Migração para quando uso de CPU ultrapassa esta porcentagem (10-90)", + "migration-delay-ms": "Atraso (ms)", + "migration-delay-ms-description": "Atraso entre lotes em milissegundos (100-10000)", + "migration-detector": "Detector de Migração", + "migration-info-text": "Migração de banco de dados é realizada uma vez e melhora o desempenho do sistema. O processo continua em segundo plano mesmo se você fechar o navegador.", + "migration-log": "Log da Migração", + "migration-markers": "Marcadores de Migração", + "migration-resume-failed": "Falha ao retomar migração", + "migration-resumed": "Migração retomada", + "migration-steps": "Etapas da Migração", + "migration-warning-text": "Não feche o navegador durante a migração. O processo continuará em segundo plano mas poderá levar mais tempo para concluir.", + "monitoring-export-failed": "Falha ao exportar dados de monitoramento", + "monitoring-refresh-failed": "Falha ao atualizar das de monitoramento", + "next": "Próximo", + "next-run": "Próxima Execução", + "of": "de", + "operation-type": "Tipo de Operação", + "overall-progress": "Progresso Geral", + "page": "Página", + "pause-migration": "Parar Migração", + "previous": "Anterior", + "refresh": "Atualizar", + "refresh-monitoring": "Atualizar Monitoramento", + "remaining-attachments": "Anexos Restantes", + "resume-migration": "Continuar Migração", + "run-once": "Executar uma vez", + "s3-attachments": "Anexos S3", + "s3-size": "Tamanho S3", + "s3-storage": "S3", + "scanning-status": "Status de Escaneamento", + "schedule": "Agendar", + "search-boards-or-operations": "Buscar quadros ou operações", + "show-list-on-minicard": "Mostrar Lista no Mini Cartão", + "showing": "Mostrando", + "start-test-operation": "Iniciar Teste de Operação", + "start-time": "Hora de início", + "step-progress": "Etapa em progresso", + "stop-migration": "Parar Migração", + "storage-distribution": "Distribuição de Armazenamento", + "system-resources": "Recursos do Sistema", + "total-attachments": "Total de Anexos", + "total-operations": "Total de Operações", + "total-size": "Tamanho Total", + "unmigrated-boards": "Quadros não migrados", + "weight": "Carga", + "idle": "Parado", + "complete": "Concluído", + "cron": "Cron" } diff --git a/imports/i18n/data/pt.i18n.json b/imports/i18n/data/pt.i18n.json index 86c39e296..2aef98106 100644 --- a/imports/i18n/data/pt.i18n.json +++ b/imports/i18n/data/pt.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "apagou o comentário %s", "activity-receivedDate": "editou a data recebida para %s de %s", "activity-startDate": "editou a data de início para %s de %s", + "allboards.starred": "Starred", + "allboards.templates": "Modelos", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "editou a data limite para %s de %s", "activity-endDate": "editou a data de fim para %s de %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Colapsar", "board-view-gantt": "Gantt", "board-view-lists": "Listas", - "bucket-example": "\"Lista de Desejos\", por exemplo", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancelar", "card-archived": "Este cartão no Arquivo.", "board-archived": "Este quadro está no Arquivo.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Título do primeiro cartão\", \"description\":\"Descrição do primeiro cartão\"}, {\"title\":\"Título do segundo cartão\",\"description\":\"Descrição do segundo cartão\"},{\"title\":\"Título do último cartão\",\"description\":\"Descrição do último cartão\"} ]", "create": "Criar", "createBoardPopup-title": "Criar Quadro", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importar quadro", "createLabelPopup-title": "Criar Etiqueta", "createCustomField": "Criar Campo", @@ -354,6 +369,10 @@ "custom-field-text": "Texto", "custom-fields": "Campos Personalizados", "date": "Data", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Rejeitar", "default-avatar": "Avatar por omissão", "delete": "Apagar", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editar a Notificação", "editProfilePopup-title": "Editar o Perfil", "email": "E-mail", + "email-address": "Email Address", "email-enrollAccount-subject": "Uma conta foi criada para si em __siteName__", "email-enrollAccount-text": "Olá __user__\nPara começar a utilizar o serviço, basta clicar na ligação abaixo.\n__url__\nObrigado.", "email-fail": "Falhou a enviar o e-mail", @@ -748,6 +768,8 @@ "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?", "delete-board": "Apagar Quadro", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Sub-tarefas para o quadro __board__", "default": "Omissão", "defaultdefault": "Omissão", @@ -755,7 +777,7 @@ "subtask-settings": "Configurações de Sub-tarefas", "card-settings": "Definições do Cartão", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Configurações das Sub-tarefas do Quadro", + "boardSubtaskSettingsPopup-title": "Configurações de Sub-tarefas", "boardCardSettingsPopup-title": "Definições do Cartão", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Depositar sub-tarefas neste quadro:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Eu", "dueCardsViewChange-choice-all": "Todos os Utilizadores", "dueCardsViewChange-choice-all-description": "Mostra todos os cartões incompletos com data *Limite* de quadros onde o utilizador tem permissões.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Cartões Defeituosos", "board-title-not-found": "Quadro '%s' não encontrado.", "swimlane-title-not-found": "Pista '%s' não encontrada.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Concluído", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Estado", + "migration-progress-details": "Detalhes", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completada", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "de", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Peso", + "idle": "Inativo", + "complete": "Concluído", + "cron": "Agendamento" } diff --git a/imports/i18n/data/pt_PT.i18n.json b/imports/i18n/data/pt_PT.i18n.json index ae0e01ee6..f355d4cb7 100644 --- a/imports/i18n/data/pt_PT.i18n.json +++ b/imports/i18n/data/pt_PT.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "apagou o comentário %s", "activity-receivedDate": "editou a data recebida para %s de %s", "activity-startDate": "editou a data de início para %s de %s", + "allboards.starred": "Starred", + "allboards.templates": "Modelos", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "editou a data limite para %s de %s", "activity-endDate": "editou a data de fim para %s de %s", "add-attachment": "Adicionar Anexo", @@ -190,7 +202,9 @@ "board-view-collapse": "Colapsar", "board-view-gantt": "Gantt", "board-view-lists": "Listas", - "bucket-example": "\"Lista de Desejos\", por exemplo", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancelar", "card-archived": "Este cartão no Arquivo.", "board-archived": "Este quadro está no Arquivo.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Título do primeiro cartão\", \"description\":\"Descrição do primeiro cartão\"}, {\"title\":\"Título do segundo cartão\",\"description\":\"Descrição do segundo cartão\"},{\"title\":\"Título do último cartão\",\"description\":\"Descrição do último cartão\"} ]", "create": "Criar", "createBoardPopup-title": "Criar Quadro", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Importar quadro", "createLabelPopup-title": "Criar Etiqueta", "createCustomField": "Criar Campo", @@ -354,6 +369,10 @@ "custom-field-text": "Texto", "custom-fields": "Campos Personalizados", "date": "Data", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Rejeitar", "default-avatar": "Avatar por omissão", "delete": "Apagar", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Editar a Notificação", "editProfilePopup-title": "Editar o Perfil", "email": "E-mail", + "email-address": "Email Address", "email-enrollAccount-subject": "Uma conta foi criada para si em __siteName__", "email-enrollAccount-text": "Olá __user__\nPara começar a utilizar o serviço, basta clicar na ligação abaixo.\n__url__\nObrigado.", "email-fail": "Falhou a enviar o e-mail", @@ -748,6 +768,8 @@ "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?", "delete-board": "Apagar Quadro", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Sub-tarefas para o quadro __board__", "default": "Omissão", "defaultdefault": "Omissão", @@ -755,7 +777,7 @@ "subtask-settings": "Configurações de Sub-tarefas", "card-settings": "Definições do Cartão", "minicard-settings": "Configurações do minicartão", - "boardSubtaskSettingsPopup-title": "Configurações das Sub-tarefas do Quadro", + "boardSubtaskSettingsPopup-title": "Configurações de Sub-tarefas", "boardCardSettingsPopup-title": "Definições do Cartão", "boardMinicardSettingsPopup-title": "Configurações do minicartão", "deposit-subtasks-board": "Depositar sub-tarefas neste quadro:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Eu", "dueCardsViewChange-choice-all": "Todos os Utilizadores", "dueCardsViewChange-choice-all-description": "Mostra todos os cartões incompletos com data *Limite* de quadros onde o utilizador tem permissões.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Cartões Defeituosos", "board-title-not-found": "Quadro '%s' não encontrado.", "swimlane-title-not-found": "Pista '%s' não encontrada.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Estado", + "migration-progress-details": "Detalhes", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completada", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "de", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ro-RO.i18n.json b/imports/i18n/data/ro-RO.i18n.json index dfef53726..4558b375a 100644 --- a/imports/i18n/data/ro-RO.i18n.json +++ b/imports/i18n/data/ro-RO.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Liste", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Anulează", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ro.i18n.json b/imports/i18n/data/ro.i18n.json index 66577e714..289a3a45e 100644 --- a/imports/i18n/data/ro.i18n.json +++ b/imports/i18n/data/ro.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ru-UA.i18n.json b/imports/i18n/data/ru-UA.i18n.json index 5cee3d0df..ad237aa07 100644 --- a/imports/i18n/data/ru-UA.i18n.json +++ b/imports/i18n/data/ru-UA.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Шаблоны", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Добавить Шаблон Контейнера", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Настройки подзадач", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Статус", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Завершен", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "из", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ru.i18n.json b/imports/i18n/data/ru.i18n.json index 95ab167a3..04a83c4c7 100644 --- a/imports/i18n/data/ru.i18n.json +++ b/imports/i18n/data/ru.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "удалил комментарий %s", "activity-receivedDate": "отредактировал дату получения на %sс %s", "activity-startDate": "отредактировал дату начала на %sс %s", + "allboards.starred": "Starred", + "allboards.templates": "Шаблоны", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "отредактировал срок исполнения на %s с %s", "activity-endDate": "отредактировал дату завершения на %s с %s", "add-attachment": "Добавить вложение", @@ -190,7 +202,9 @@ "board-view-collapse": "Свернуть", "board-view-gantt": "Диаграмма Ганта", "board-view-lists": "Списки", - "bucket-example": "Например “Список дел”", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Отмена", "card-archived": "Эта карточка перемещена в архив", "board-archived": "Эта доска перемещена в архив.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Название первой карточки\", \"description\":\"Описание первой карточки\"}, {\"title\":\"Название второй карточки\",\"description\":\"Описание второй карточки\"},{\"title\":\"Название последней карточки\",\"description\":\"Описание последней карточки\"} ]", "create": "Создать", "createBoardPopup-title": "Создать доску", + "createTemplateContainerPopup-title": "Добавить Шаблон Контейнера", "chooseBoardSourcePopup-title": "Импортировать доску", "createLabelPopup-title": "Создать метку", "createCustomField": "Создать поле", @@ -354,6 +369,10 @@ "custom-field-text": "Текст", "custom-fields": "Настраиваемые поля", "date": "Дата", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Отклонить", "default-avatar": "Аватар по умолчанию", "delete": "Удалить", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Редактировать уведомления", "editProfilePopup-title": "Редактировать профиль", "email": "Эл.почта", + "email-address": "Email Address", "email-enrollAccount-subject": "Аккаунт создан для вас здесь __url__", "email-enrollAccount-text": "Привет __user__,\n\nДля того, чтобы начать использовать сервис, просто нажми на ссылку ниже.\n\n__url__\n\nСпасибо.", "email-fail": "Отправка письма на EMail не удалась", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Все списки, карточки, метки и действия будут удалены, и вы не сможете восстановить содержимое доски. Отменить нельзя.", "boardDeletePopup-title": "Удалить доску?", "delete-board": "Удалить доску", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Подзадача для доски __board__", "default": "По умолчанию", "defaultdefault": "По умолчанию", @@ -755,7 +777,7 @@ "subtask-settings": "Настройки подзадач", "card-settings": "Настройки карточки", "minicard-settings": "Настройки миникарточки", - "boardSubtaskSettingsPopup-title": "Настройки подзадач для доски", + "boardSubtaskSettingsPopup-title": "Настройки подзадач", "boardCardSettingsPopup-title": "Настройки карточки", "boardMinicardSettingsPopup-title": "Настройки миникарточки", "deposit-subtasks-board": "Отправлять подзадачи на доску:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Мне", "dueCardsViewChange-choice-all": "Все пользователи", "dueCardsViewChange-choice-all-description": "Показать все незавершенные карточки с установленным сроком с досок для которых у пользователя есть разрешения.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Просроченные карточки", "board-title-not-found": "Доска '%s' не найдена.", "swimlane-title-not-found": "Дорожка '%s' не найдена.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Завершено", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Статус", + "migration-progress-details": "Детали", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Завершен", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "из", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Вес", + "idle": "Простой", + "complete": "Завершено", + "cron": "Планировщик" } diff --git a/imports/i18n/data/sk.i18n.json b/imports/i18n/data/sk.i18n.json index fd70f83ab..8dc0e0b52 100644 --- a/imports/i18n/data/sk.i18n.json +++ b/imports/i18n/data/sk.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Pridať prílohu", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Zoznamy", - "bucket-example": "Napríklad \"Rozpočet\".", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Zrušiť", "card-archived": "This card is moved to Archive.", "board-archived": "Táto nástenka bude premiestnená do archívu.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Vytvoriť", "createBoardPopup-title": "Vytvoriť nástenku", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Vytvoriť štítok", "createCustomField": "Vytvoriť pole", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Dátum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Zmazať", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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": "Zmazať nástenku?", "delete-board": "Zmazať nástenku", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Nástenka '%s' sa nenašla.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/sl.i18n.json b/imports/i18n/data/sl.i18n.json index e7ced6ea9..6b28083b9 100644 --- a/imports/i18n/data/sl.i18n.json +++ b/imports/i18n/data/sl.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "izbrisal komentar %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Predloge", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Dodaj priponko", @@ -190,7 +202,9 @@ "board-view-collapse": "Skrči", "board-view-gantt": "Gantt", "board-view-lists": "Seznami", - "bucket-example": "Kot na primer \"Življenjski seznam\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Prekliči", "card-archived": "Kartica je premaknjena v arhiv.", "board-archived": "Tabla je premaknjena v arhiv.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"naslov\": \"Naslov prve kartice\", \"opis\":\"Opis prve kartice\"}, {\"naslov\":\"Opis druge kartice\",\"opis\":\"Opis druge kartice\"},{\"naslov\":\"Naslov zadnje kartice\",\"opis\":\"Opis zadnje kartice\"} ]", "create": "Ustvari", "createBoardPopup-title": "Ustvari tablo", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Uvozi tablo", "createLabelPopup-title": "Ustvari oznako", "createCustomField": "Ustvari polje", @@ -354,6 +369,10 @@ "custom-field-text": "Besedilo", "custom-fields": "Poljubna polja", "date": "Datum", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Zavrni", "default-avatar": "Privzeti avatar", "delete": "Briši", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Uredi obvestilo", "editProfilePopup-title": "Uredi profil", "email": "E-pošta", + "email-address": "Email Address", "email-enrollAccount-subject": "Up. račun ustvarjen za vas na __siteName__", "email-enrollAccount-text": "Pozdravljeni __user__,\n\nZa začetek uporabe kliknite spodnjo povezavo.\n\n__url__\n\nHvala.", "email-fail": "Pošiljanje e-pošte ni uspelo", @@ -748,6 +768,8 @@ "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?", "delete-board": "Izbriši tablo", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Podopravila za tablo", "default": "Privzeto", "defaultdefault": "Privzeto", @@ -755,7 +777,7 @@ "subtask-settings": "Nastavitve podopravil", "card-settings": "Nastavitve kartice", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Nastavitve podopravil table", + "boardSubtaskSettingsPopup-title": "Nastavitve podopravil", "boardCardSettingsPopup-title": "Nastavitve kartice", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deponiraj podopravila na tablo:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "zaključen", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/sr.i18n.json b/imports/i18n/data/sr.i18n.json index d8c1904ab..4fbf8a0ba 100644 --- a/imports/i18n/data/sr.i18n.json +++ b/imports/i18n/data/sr.i18n.json @@ -1,235 +1,249 @@ { "accept": "Прихвати", "act-activity-notify": "Обавештење о последњим променама", - "act-addAttachment": "додао прилог __attachment__ на картици __card__ на деоници __list__ на стази __swimlane__ у пословној књизи __board__", - "act-deleteAttachment": "уклонио прилог __attachment__ са картице __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-addSubtask": "додао подзадатак __subtask__ на картицу __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-addLabel": "Залепио налепницу __label__ на картицу __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-addedLabel": "Залепљена је налепница __label__ на картицу __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-removeLabel": "Скинуо налепницу __label__ са картице __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-removedLabel": "Скинута је налепница __label__ са картице __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-addChecklist": "додао списак за обавити __checklist__ на задатак __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-addChecklistItem": "додао ставку __checklistItem__ на списак за обавити __checklist__ задатка __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-removeChecklist": "уклонио списак за обавити __checklist__ са задатка __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-removeChecklistItem": "уклонио ставку __checklistItem__ са списка за обавити __checkList__ задатка __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-checkedItem": "обавио __checklistItem__ са списка __checklist__ на задатку __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-uncheckedItem": "вратио да се поново обави __checklistItem__ са списка __checklist__ на задатку __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-completeChecklist": "обавио све са списка __checklist__ на задатку __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-uncompleteChecklist": "није обављено све са списка __checklist__ на задатку __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-addComment": "изразио мишљење на картици __card__: __comment__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-editComment": "изменио мишљење на картици __card__:__comment__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-deleteComment": "повукао мишљење на картици __card__:__comment__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-createBoard": "Отворена је сасвим нова пословна књига __board__", - "act-createSwimlane": "Додата је сасвим нова стаза __swimlane__ у пословној књизи __board__", - "act-createCard": "додата је сасвим нова картица са задатком __card__ на деоници __list__ на стази __swimlane__ у пословној књизи __board__", - "act-createCustomField": "направљено сасвим ново поље __customField__ у пословној књизи __board__", - "act-deleteCustomField": "избрисано сасвим ново поље __customField__ у пословној књизи __board__", - "act-setCustomField": "измењено сасвим ново поље __customField__:__customFieldValue__ на картици са задатком __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board", - "act-createList": "придодата деоница __list__ у пословној књизи __board__", - "act-addBoardMember": "примљен сарадник __member__ у пословној књизи __board__", - "act-archivedBoard": "Пословна књига __board__ је премештена у архив", - "act-archivedCard": "Картица са задатком __card__ са деонице __list__ стазе __swimlane__ из пословне књиге __board__ однешена у архив", - "act-archivedList": "Деоница __list__ стазе __swimlane__ из пословне књиге __board__ премештена у архив", - "act-archivedSwimlane": "Стаза __swimlane__ из пословне књиге __board__ однешена у архив", - "act-importBoard": "увезао књигу пословања __board__", - "act-importCard": "увезао картицу са задатком __card__ на деоници __list__ на стази __swimlane__ у пословној књизи __board__", - "act-importList": "увезао деоницу __list__ на стазу __swimlane__ у пословној књизи __board__", - "act-joinMember": "примио сарадника __member__ на картицу __card__ на деоници __list__ стазе __swimlane__ у пословној књизи __board__", - "act-moveCard": "преместио картицу __card__ из пословне књиге __board__ са старе деонице __oldList__ старе стазе __oldSwimlane__ на деоницу __list__ нове стазе __swimlane__", - "act-moveCardToOtherBoard": "преместио картицу __card__ са старе деонице __oldList__ старе стазе __oldSwimlane__ из старе пословне књиге __oldBoard__ на деоницу __list__ стазе __swimlane__ у пословну књигу __board__", - "act-removeBoardMember": "удаљио сарадника __member__ из пословне књиге __board__", - "act-restoredCard": "обновио картицу са задатком __card__ на деоници __list__ у стази __swimlane__ у пословној књизи __board__", - "act-unjoinMember": "удаљио сарадника __member__ са картице __card__ на деоници __list__ стазе __swimlane__ из пословне књиге __board__", + "act-addAttachment": "унео предметну грађу __attachment__ у предмет __card__ у делу __list__ поступка __swimlane__ међу списе __board__", + "act-deleteAttachment": "уклонио предметну грађу __attachment__ из предмета __card__ у делу __list__ поступка __swimlane__ из списа __board__", + "act-addSubtask": "је издвојио посао __subtask__ из предмета __card__ у __list__ делу __swimlane__ поступка у списима __board__", + "act-addLabel": "Залепио налепницу __label__ на омот предмета __card__ у делу __list__ поступка __swimlane__ у списима __board__", + "act-addedLabel": "Залепљена је налепница __label__ на омот предмета __card__ у делу __list__ поступка __swimlane__ у списима __board__", + "act-removeLabel": "Скинуо је налепницу __label__ са омота предмета __card__ у делу __list__ поступка __swimlane__ из списа __board__", + "act-removedLabel": "Скинута је налепница __label__ са омота предмета __card__ у делу __list__ поступка __swimlane__ из списа __board__", + "act-addChecklist": "је додао списак радњи __checklist__ у предмет __card__ у __list__ делу поступка __swimlane__ заведеног у списима __board__", + "act-addChecklistItem": "је додао ставку __checklistItem__ на списак __checklist__ у предмету __card__ у __list__ поступка __swimlane__ у списима __board__", + "act-removeChecklist": "је уклонио списак радњи __checklist__ из предмета __card__ у __list__ делу поступка __swimlane__ у списима __board__", + "act-removeChecklistItem": "је уклонио ставку __checklistItem__ са списка __checkList__ предмета __card__ у __list__ делу __swimlane__ у списима __board__", + "act-checkedItem": "је прецртао ставку __checklistItem__ са списка __checklist__ у предмету __card__ у __list__ делу __swimlane__ у списима __board__", + "act-uncheckedItem": "је вратио да се поново обави __checklistItem__ радња са списка __checklist__ у предмету __card__ у __list__ делу __swimlane__ у списима __board__", + "act-completeChecklist": "је испунио све са списка __checklist__ у предмету __card__ у __list__ делу __swimlane__ у списима __board__", + "act-uncompleteChecklist": "није испунио све са списка __checklist__ у предмету __card__ у __list__ делу __swimlane__ у списима __board__", + "act-addComment": "изразио следеће мишљење у расправи у предмету __card__: __comment__ у делу __list__ поступка __swimlane__ у списима __board__", + "act-editComment": "допунио став у расправи у предмету __card__:__comment__ у делу __list__ поступка __swimlane__ у списима __board__", + "act-deleteComment": "повукао мишљење у предмету __card__:__comment__ у делу __list__ поступка __swimlane__ у списима __board__", + "act-createBoard": "је увео нове списе са деловодним бројем __board__", + "act-createSwimlane": "је додао нови предметни ток __swimlane__ међу списе __board__", + "act-createCard": "је додао нови предмет __card__ у делу __list__ поступка __swimlane__ међу списе __board__", + "act-createCustomField": "је додао нову рубрику __customField__ међу списе __board__", + "act-deleteCustomField": "је избрисао рубрику __customField__ из списа __board__", + "act-setCustomField": "је изменио запис у рубрици __customField__:__customFieldValue__ у предмету __card__ у __list__ делу поступка __swimlane__ у списима __board", + "act-createList": "је придодао део поступка __list__ међу списе __board__", + "act-addBoardMember": "примљен сарадник __member__ за рад на списима __board__", + "act-archivedBoard": "Списи __board__ су спаковани у архив", + "act-archivedCard": "Предмет __card__ из дела __list__ поступка __swimlane__ из списа __board__ је спакован у архив", + "act-archivedList": "Део __list__ поступка __swimlane__ из списа __board__ је спакован у архив", + "act-archivedSwimlane": "Врста поступка __swimlane__ из списа __board__ је спакована у архив", + "act-importBoard": "унео списе __board__", + "act-importCard": "унео предмет __card__ у делу __list__ поступка __swimlane__ у списе __board__", + "act-importList": "унео део __list__ поступка __swimlane__ у списе __board__", + "act-joinMember": "примљен сарадник __member__ да ради на предмету __card__ у делу __list__ поступка __swimlane__ у списима __board__", + "act-moveCard": "преместио предмет __card__ из списа __board__ са старог дела __oldList__ поступка __oldSwimlane__ у нови део __list__ поступка __swimlane__", + "act-moveCardToOtherBoard": "преместио предмет __card__ са старог дела __oldList__ поступка __oldSwimlane__ из старих списа __oldBoard__ у део __list__ поступка __swimlane__ међу списе __board__", + "act-removeBoardMember": "изузео сарадника __member__ из списа __board__", + "act-restoredCard": "опоравио предмет __card__ у делу поступка __list__ из поступка __swimlane__ из списа __board__", + "act-unjoinMember": "изузео сарадника __member__ са предмета __card__ у делу поступка __list__ из поступка __swimlane__ из списа __board__", "act-withBoardTitle": "__board__", "act-withCardTitle": "[__board__] __card__", "actions": "Радње", - "activities": "Последње промене", + "activities": "Дневник промена", "activity": "Последња промена", - "activity-added": "додао %s у %s", + "activity-added": "је додао %s у %s", "activity-archived": "%s премештено у архиву", - "activity-attached": "приложио %s у %s", - "activity-created": "направио %s", - "activity-changedListTitle": "renamed list to %s", - "activity-customfield-created": "направио сасвим ново поље %s", + "activity-attached": "унео предметну грађу %s у %s", + "activity-created": "је направио %s", + "activity-changedListTitle": "је преименовао део поступка у %s", + "activity-customfield-created": "је додао рубрику %s", "activity-excluded": "изузет %s из %s", "activity-imported": "увезао %s у %s из %s", "activity-imported-board": "увезао %s из %s", "activity-joined": "спојио %s", - "activity-moved": "преместио %s из %s у %s", + "activity-moved": "је преместио %s из %s у %s", "activity-on": "на %s", "activity-removed": "уклонио %s из %s", "activity-sent": "послао %s %s-у", "activity-unjoined": "раставио %s", - "activity-subtask-added": "додао подзадатак за %s", - "activity-checked-item": "обављено %s са списка %s од %s", - "activity-unchecked-item": "није обављено %s са списка %s од %s", - "activity-checklist-added": "деоница је додата у %s", - "activity-checklist-removed": "уклонио списак за обавити са %s", - "activity-checklist-completed": "испуњеност задатака са списка %s од %s", - "activity-checklist-uncompleted": "списак није испуњен %s од %s", - "activity-checklist-item-added": "придодата ставка на списак за обавити '%s' у %s", - "activity-checklist-item-removed": "избачена ставка са списка за обавити из '%s' у %s", + "activity-subtask-added": "је издвојио посао из предмета %s", + "activity-checked-item": "пријављује да је обавио задатак %s са списка %s у предмету %s", + "activity-unchecked-item": "повлачи пријаву да је обавио задатак %s са списка %s у предмету %s", + "activity-checklist-added": "је унео предметну радњу у предмет %s", + "activity-checklist-removed": "је уклонио предметну радњу из предмета %s", + "activity-checklist-completed": "је испунио све са списка предметне радње %s у предмету %s", + "activity-checklist-uncompleted": "ипак није испунио све са списка предметне радње %s у предмету %s", + "activity-checklist-item-added": "је придодао ставку '%s' у предметну радњу %s", + "activity-checklist-item-removed": "је ставку '%s' избацио из предметне радње %s", "add": "Додај", - "activity-checked-item-card": "испуњена обавеза %s у списку за обавити %s", - "activity-unchecked-item-card": "неиспуњена обавеза %s на списку за обавити %s", - "activity-checklist-completed-card": "испуњене обавезе са списка __checklist__ на картици __card__ деонице __list__ на стази __swimlane__ пословне књиге __board__", + "activity-checked-item-card": "је испунио обавезу %s као ставку предметне радње %s", + "activity-unchecked-item-card": "је означио обавезу %s ипак као неиспуњен део предметне радње %s", + "activity-checklist-completed-card": "испуњене обавезе са списка __checklist__ у оквиру предмета __card__ у __list__ делу поступка __swimlane__ заведеног у списима __board__", "activity-checklist-uncompleted-card": "нису испуњене обавезе са списка %s", "activity-editComment": "променио мишљење", "activity-deleteComment": "повучено мишљење", - "activity-receivedDate": "измењен датум пријема на %s са %s", - "activity-startDate": "измењен почетни датум на %s са %s", - "activity-dueDate": "измењен крајњи рок на %s са %s", - "activity-endDate": "измењено време завршетка на %s са %s", - "add-attachment": "Додај прилог", - "add-board": "Уведи пословну књигу", - "add-template": "Додај предложак", - "add-card": "Додај картицу са задатком", - "add-card-to-top-of-list": "Додај картицу/задатак на врх деонице", - "add-card-to-bottom-of-list": "Додај картицу/задатак на дно деонице", - "setListWidthPopup-title": "Set Widths", - "set-list-width": "Set Widths", - "set-list-width-value": "Set Min & Max Widths (pixels)", - "list-width-error-message": "List widths must be integers greater than 100", - "keyboard-shortcuts-enabled": "Keyboard shortcuts enabled. Click to disable.", - "keyboard-shortcuts-disabled": "Keyboard shortcuts disabled. Click to enable.", - "setSwimlaneHeightPopup-title": "Подеси висину стазе", - "set-swimlane-height": "Подеси висину стазе", - "set-swimlane-height-value": "Висина стазе (у пикселима)", - "swimlane-height-error-message": "Висина стазе мора бити позитиван број", - "add-swimlane": "Додај стазу", - "add-subtask": "Додај подзадатак", - "add-checklist": "Додај списак за обавити", - "add-checklist-item": "Додај нову ставку на списак", - "close-add-checklist-item": "Затвори образац за додавање ставке на списак за обавити", - "close-edit-checklist-item": "Затвори образац за уређивање ставке списка за обавити", - "convertChecklistItemToCardPopup-title": "Претвори ставку за обавити у облик картице са задатком", - "add-cover": "Додајте насловну слику на мини картицу", + "activity-receivedDate": "је изменио датум и време пријема на %s у предмету %s", + "activity-startDate": "је изменио датум и време %s кад почиње да ради на предмету %s", + "allboards.starred": "Истакнути", + "allboards.templates": "Обрасци", + "allboards.remaining": "Нерасподељени", + "allboards.workspaces": "Радни простор", + "allboards.add-workspace": "Прошири радни простор", + "allboards.add-workspace-prompt": "Назив радног простора", + "allboards.add-subworkspace": "Додај радни кутак", + "allboards.add-subworkspace-prompt": "Назив за радни кутак", + "allboards.edit-workspace": "Преименовање радног простора", + "allboards.edit-workspace-name": "Назив радног простора", + "allboards.edit-workspace-icon": "Слика за радни простор (код)", + "multi-selection-active": "Штиклирајте да би изабрали списе", + "activity-dueDate": "је изменио крајњи рок на %s у предмету %s", + "activity-endDate": "је изменио датум и време %s кад је окончао предмет %s", + "add-attachment": "Додај предметну грађу", + "add-board": "Уведи нове списе", + "add-template": "Додај образац", + "add-card": "Додај предмет", + "add-card-to-top-of-list": "Додај предмет на врх", + "add-card-to-bottom-of-list": "Додај предмет на дно", + "setListWidthPopup-title": "Ширина дела поступка", + "set-list-width": "Постави ширину", + "set-list-width-value": "Мин/Макс. ширина (px)", + "list-width-error-message": "Ширина дела поступка мора бити цео број већи од 100", + "keyboard-shortcuts-enabled": "Пречице са тастатуре су укључене.", + "keyboard-shortcuts-disabled": "Пречице са тастатуре су искључене.", + "setSwimlaneHeightPopup-title": "Подеси висину у овој врсти поступка", + "set-swimlane-height": "Подеси висину овог поступка", + "set-swimlane-height-value": "Висина ове врсте поступка (у тачкама)", + "swimlane-height-error-message": "Висина тока поступка мора бити позитиван број", + "add-swimlane": "Додај врсту поступка", + "add-subtask": "Издвоји посао", + "add-checklist": "Додај предметну радњу", + "add-checklist-item": "Додај помоћну предметну радњу", + "close-add-checklist-item": "Окончај додавање помоћних предметних радњи", + "close-edit-checklist-item": "Прекини измену помоћне предметне радње", + "convertChecklistItemToCardPopup-title": "Материјал ⇨ нов предмет", + "add-cover": "Осликани омот предмета", "add-label": "Додај налепницу", "add-list": "Додај деоницу", "add-after-list": "Додај након листе", "add-members": "Прими сараднике", - "added": "Додао", + "added": "додао", "addMemberPopup-title": "Сарадници", "memberPopup-title": "Избор сарадника", "admin": "Управник", - "admin-desc": "Може да гледа и мења картице, удаљи сараднике и мења правила књиге пословања", - "admin-announcement": "Најава", - "admin-announcement-active": "Дозволи системска обавештења", - "admin-announcement-title": "Обавештење од управника", - "all-boards": "Све пословне књиге", - "and-n-other-card": "И __count__ осталих картица", - "and-n-other-card_plural": "И __count__ осталих картица", + "admin-desc": "Може да има и увид и пун приступ предметима, може да одабира сараднике на њима и може да постави правила рада на списима.", + "admin-announcement": "Јавни разглас", + "admin-announcement-active": "Пусти на јавни разглас", + "admin-announcement-title": "Јавно саопштење управника:", + "all-boards": "Полица са списима", + "and-n-other-card": "И __count__ други предмет", + "and-n-other-card_plural": "И __count__ других предмета", "apply": "Примени", "app-is-offline": "Исчитавам, молим да сачекате. Освежавање стране ће изазвати губитак података. Ако повлачење података не ради, молим да проверите да ли је сервер заустављен.", "app-try-reconnect": "Покушавам да се поново повежем.", - "archive": "Премести у архиву", - "archive-all": "Премести све у архиву", - "archive-board": "Премести пословну књигу у архиву", - "archive-board-confirm": "Are you sure you want to archive this board?", - "archive-card": "Премести картицу са задатком у архиву", - "archive-list": "Премести деоницу у архиву", - "archive-swimlane": "Премести стазу у архиву", - "archive-selection": "Премести изабрано у архиву", - "archiveBoardPopup-title": "Преместићете ову пословну књигу у архиву?", - "archived-items": "Архивирај", - "archived-boards": "Пословне књиге из архиве", - "restore-board": "Извуци пословну књигу из архиве", - "no-archived-boards": "Нема књига пословања у архиви.", - "archives": "Архива", - "template": "Предложак", - "templates": "Предлошци", - "template-container": "Сандук са предлошцима", - "add-template-container": "Додај сандук са предлошцима", + "archive": "Спакуј у архиву", + "archive-all": "Спакуј све у архиву", + "archive-board": "Спакуј ове списе у архиву", + "archive-board-confirm": "Да ли сте сигурни да желите да спакујете ове списе у архив?", + "archive-card": "Спакуј предмет у архиву", + "archive-list": "Спакуј овај део поступка у архиву", + "archive-swimlane": "Спакуј овај ток поступка у архиву", + "archive-selection": "Спакуј изабрано у архиву", + "archiveBoardPopup-title": "Архивираћете ове списе?", + "archived-items": "Архива", + "archived-boards": "Архивирани списи", + "restore-board": "Извуци списе из архиве", + "no-archived-boards": "Архива је празна!", + "archives": "Архиве", + "template": "Образац", + "templates": "Обрасци", + "template-container": "Сандук са обрасцима", + "add-template-container": "Додај сандук са обрасцима", "assign-member": "Додели члана", "attached": "Приложено", "attachment": "Приложени документ", "attachment-delete-pop": "Брисање приложеног документа је трајно. Опозив ове радње неће бити могућ.", "attachmentDeletePopup-title": "Обрисаћете приложени документ?", - "attachments": "Приложени документи", - "auto-watch": "Чим се књига пословања отвори почни да је пратиш", - "avatar-too-big": "Ова сличица је превелика (__size__ max)", + "attachments": "Предметна грађа", + "auto-watch": "Чим настану нови списи почни да прикупљаш све промене", + "avatar-too-big": "Слика је превелика (__size__ max)", "back": "Назад", - "board-change-color": "Обоји корице књиге пословања", - "board-change-background-image": "Насловница пословне књиге", - "board-background-image-url": "Веза до слике за насловницу пословне књиге", - "add-background-image": "Додај позадинску слику", - "remove-background-image": "Уклони позадинску слику", - "show-at-all-boards-page" : "Прикажи на полазној страни где су све пословне књиге", - "board-info-on-my-boards" : "Правила за све књиге пословања", - "boardInfoOnMyBoardsPopup-title" : "Правила за све књиге пословања", - "boardInfoOnMyBoards-title": "Правила за све пословне књиге", - "show-card-counter-per-list": "Прикажи број картица на деоници", - "show-board_members-avatar": "Прикажи сличице сарадника/корисника пословне књиге", + "board-change-color": "Обоји омот списа", + "board-change-background-image": "Осликај подлогу списа", + "board-background-image-url": "Веза до слике", + "add-background-image": "Искористи слику за подлогу", + "remove-background-image": "Уклони подлогу", + "show-at-all-boards-page" : "Смести на полицу са списима", + "board-info-on-my-boards" : "Списи у мојој надлежности", + "boardInfoOnMyBoardsPopup-title" : "Списи у мојој надлежности", + "boardInfoOnMyBoards-title": "Списи у мојој надлежности", + "show-card-counter-per-list": "Прикажи бројач предмета на сваком делу тока поступка", + "show-board_members-avatar": "Прикажи слике сарадника на омоту списа", "board-nb-stars": "%s звездица", - "board-not-found": "Књига пословања није пронађена", - "board-private-info": "Ова пословна књига ће бити приватна.", - "board-public-info": "Ова пословна књига ће бити јавна.", - "board-drag-drop-reorder-or-click-open": "Држите и пренесите да би пресложили иконице пословне књиге. Притисните на иконицу да отворите књигу пословања.", - "boardChangeColorPopup-title": "Промени позадину насловне стране књиге пословања", - "boardChangeBackgroundImagePopup-title": "Промена насловнице пословне књиге", - "allBoardsChangeColorPopup-title": "Обоји корице књиге пословања", - "allBoardsChangeBackgroundImagePopup-title": "Насловница пословне књиге", - "boardChangeTitlePopup-title": "Преименуј наслов на пословној књизи", - "boardChangeVisibilityPopup-title": "Промени видљивост", - "boardChangeWatchPopup-title": "Промени праћење", - "boardMenuPopup-title": "Правила коришћења пословне књиге", + "board-not-found": "Спис није пронађен", + "board-private-info": "Ови списи су видљиви само сарадницима.", + "board-public-info": "Ови списи су видљиви свима.", + "board-drag-drop-reorder-or-click-open": "Притисните и задржите па превуците да би пресложили списе. Притисните на сличицу да отворите списе.", + "boardChangeColorPopup-title": "Промени боју омота ових списа", + "boardChangeBackgroundImagePopup-title": "Списи на осликаној подлози", + "allBoardsChangeColorPopup-title": "Зид у боји", + "allBoardsChangeBackgroundImagePopup-title": "Осликани зид", + "boardChangeTitlePopup-title": "Деловодни број и опис", + "boardChangeVisibilityPopup-title": "Промена тајности ових списа", + "boardChangeWatchPopup-title": "Пријем обавештења", + "boardMenuPopup-title": "Рад са списима", "allBoardsMenuPopup-title": "Подешавања", - "boardChangeViewPopup-title": "Распоред у књизи пословања", - "boards": "Књиге пословања", - "board-view": "Прегледност пословне књиге", - "desktop-mode": "Desktop Mode", - "mobile-mode": "Mobile Mode", - "mobile-desktop-toggle": "Toggle between Mobile and Desktop Mode", - "zoom-in": "Zoom In", - "zoom-out": "Zoom Out", - "click-to-change-zoom": "Click to change zoom level", - "zoom-level": "Zoom Level", - "enter-zoom-level": "Enter zoom level (50-300%):", + "boardChangeViewPopup-title": "Поглед на списе", + "boards": "Списи", + "board-view": "Поглед на списе", + "desktop-mode": "Приказ прилагођен за екран рачунара", + "mobile-mode": "Приказ прилагођен за екран мобилног уређаја", + "mobile-desktop-toggle": "Замени приказ прилагођен за рачунар/мобилни", + "zoom-in": "Приближи", + "zoom-out": "Одаљи", + "click-to-change-zoom": "Лупа", + "zoom-level": "Ниво", + "enter-zoom-level": "Задајте ниво (50-300%):", "board-view-cal": "Календар", - "board-view-swimlanes": "Стазе", - "board-view-collapse": "Сажми", + "board-view-swimlanes": "Врсте поступака", + "board-view-collapse": "Скупи", "board-view-gantt": "Гант", "board-view-lists": "Деонице", - "bucket-example": "На пример \"Списак задатака\"", + "bucket-example": "Деловодни број (на пример 4/2025)", + "calendar-previous-month-label": "Претходни месец", + "calendar-next-month-label": "Наредни месец", "cancel": "Откажи", - "card-archived": "Ова картица је архивирана.", - "board-archived": "Ова књига пословања је премештена у архиву.", - "card-comments-title": "На овој картици је исказано %s мишљења.", - "card-delete-notice": "Брисање је трајно. Изгубићете све у вези са овом картицом са задацима.", - "card-delete-pop": "Све радње ће бити уклоњене са списка промена и картица са задатком неће моћи бити опорављена. Опозив ове радње неће бити могућ.", - "card-delete-suggest-archive": "Оно што можете је да картицу са задатком архивирате (чиме се све у вези ње очувава) а где је ипак избацујете из књиге пословања.", - "card-archive-pop": "Након њеног архивирања, картица више неће бити видљива на овој деоници.", - "card-archive-suggest-cancel": "Касније,ипак, можете извући и вратити картицу из архиве.", - "card-due": "Рок", - "card-due-on": "Рок истиче", + "card-archived": "Предмет је архивиран.", + "board-archived": "Ови списи су премештени у архиву.", + "card-comments-title": "У овом предмету у расправи је исказано %s мишљења.", + "card-delete-notice": "Брисање је трајно. Изгубићете све у вези са овим предметом.", + "card-delete-pop": "Читав записник ће бити уклоњен и предмет неће моћи бити опорављен. Опозив ове радње неће бити могућ.", + "card-delete-suggest-archive": "Оно што можете је да предмете исчупате из списа архивирањем (тада се записник чува).", + "card-archive-pop": "Након архивирања, предмет више неће бити видљив у овом делу тока поступка.", + "card-archive-suggest-cancel": "Касније ипак можете извући и вратити предмет из архиве.", + "card-due": "Орочен", + "card-due-on": "Предмету истиче рок дана", "card-spent": "Утрошено време", - "card-edit-attachments": "Уреди прилоге", - "card-edit-custom-fields": "Уреди сасвим нова поља", + "card-edit-attachments": "Рад са предметном грађом", + "card-edit-custom-fields": "Придружене рубрике", "card-edit-labels": "Уреди налепнице", "card-edit-members": "Осмисли сарадничку мрежу", - "card-labels-title": "Залепи налепницу на картицу.", - "card-members-title": "Додај или уклони сараднике из књиге пословања са картице.", - "card-start": "Почетак", - "card-start-on": "Почиње", + "card-labels-title": "Залепи налепницу на омот предмета.", + "card-members-title": "Одабир сарадника на списима за овај предмет.", + "card-start": "Започет", + "card-start-on": "Предмет започет дана", "cardAttachmentsPopup-title": "Прилог долази са", - "cardCustomField-datePopup-title": "Промени датум", - "cardCustomFieldsPopup-title": "Уреди сасвим нова поља", - "cardStartVotingPopup-title": "Ново гласање", - "positiveVoteMembersPopup-title": "Гласали За", - "negativeVoteMembersPopup-title": "Гласали Против", - "card-edit-voting": "Постави правила гласања", - "editVoteEndDatePopup-title": "Гласачко место се затвара", - "allowNonBoardMembers": "Дозволи свим корисницима са пријавом", - "vote-question": "Гласачко питање", - "vote-public": "Прикажи резултате гласања", + "cardCustomField-datePopup-title": "Промени датум у рубрици", + "cardCustomFieldsPopup-title": "Придружене рубрике", + "cardStartVotingPopup-title": "Саветодавни референдум", + "positiveVoteMembersPopup-title": "Гласали „За“", + "negativeVoteMembersPopup-title": "Гласали „Против“", + "card-edit-voting": "Јавно гласање", + "editVoteEndDatePopup-title": "Када се гласачко место затвара", + "allowNonBoardMembers": "Дај право гласа и онима који немају увид у ове списе", + "vote-question": "Питање на јавном гласању", + "vote-public": "Прикажи резултате јавног гласања", "vote-for-it": "за", "vote-against": "против", "deleteVotePopup-title": "Избрисаћете гласање?", "vote-delete-pop": "Брисање има трајни карактер. Све у вези са овим гласањем ће бити неповратно избрисано.", "cardStartPlanningPokerPopup-title": "Започни договор за партију покера", - "card-edit-planning-poker": "Договор за партију покера", + "card-edit-planning-poker": "Такмичење", "editPokerEndDatePopup-title": "Промени крајњи датум до кад траје гласање за партију покера", - "poker-question": "Договор за партију покера", + "poker-question": "Играмо карте", "poker-one": "1", "poker-two": "2", "poker-three": "3", @@ -247,100 +261,101 @@ "set-estimation": "Постави прогнозу", "deletePokerPopup-title": "Уклони договор за партију покера?", "poker-delete-pop": "Брисање има трајни карактер. Изгубићете све радње у вези овог плана за партију покера.", - "cardDeletePopup-title": "Обрисаћете картицу?", - "cardArchivePopup-title": "Архивираћете картицу?", - "cardDetailsActionsPopup-title": "Радње на картицама са задацима", + "cardDeletePopup-title": "Обрисаћете предмет?", + "cardArchivePopup-title": "Архивираћете предмет?", + "cardDetailsActionsPopup-title": "Шире радње на предмету", "cardLabelsPopup-title": "Налепнице", "cardMembersPopup-title": "Сарадничка мрежа", "cardMorePopup-title": "Више", - "cardTemplatePopup-title": "Направи предложак", - "cards": "Картице", - "cards-count": "Картице", - "cards-count-one": "Картица", + "cardTemplatePopup-title": "Направи образац", + "cards": "Предмети", + "cards-count": "Предмета", + "cards-count-one": "Предмет", "casSignIn": "Пријави се користећи CAS", - "cardType-card": "Картица са задацима", - "cardType-linkedCard": "Повезана картица са задацима", - "cardType-linkedBoard": "Повезана деоница", + "cardType-card": "Предмет", + "cardType-linkedCard": "Везани предмет", + "cardType-linkedBoard": "Везани списи", "change": "Промени", - "change-avatar": "Промени сличицу", + "change-avatar": "Моја слика", "change-password": "Промени лозинку", - "change-permissions": "Промени дозволе", - "change-settings": "Неколико важних правила", - "changeAvatarPopup-title": "Промени сличицу", + "change-permissions": "Промени улогу", + "change-settings": "Поставка предмета", + "changeAvatarPopup-title": "Моја слика", "changeLanguagePopup-title": "Избор језика", "changePasswordPopup-title": "Промена лозинке", - "changePermissionsPopup-title": "Промени дозволе", - "changeSettingsPopup-title": "Неколико важних правила", - "subtasks": "Подзадаци", - "checklists": "Спискови", - "click-to-star": "Притисни да означиш звездицом ову књигу пословања.", - "click-to-unstar": "Притисни да уклониш звездицу са ове пословне књиге.", + "changePermissionsPopup-title": "Избор улоге", + "changeSettingsPopup-title": "Општа поставка предмета", + "subtasks": "Издвојени послови", + "checklists": "Предметне радње", + "click-to-star": "Означи звездицом ове списе.", + "click-to-unstar": "Уклони звездицу са ових списа.", "click-to-enable-auto-width": "Auto list width disabled. Click to enable.", "click-to-disable-auto-width": "Auto list width enabled. Click to disable.", "auto-list-width": "Auto list width", "clipboard": "Из историје или пренеси и испусти", "close": "Заклопи", - "close-board": "Заклопи књигу пословања", - "close-board-pop": "Моћи ћете да повратите пословну књигу притиском на дугме “Архив” са почетног заглавља.", - "close-card": "Затвори картицу са задатком", + "close-board": "Заклопи списе", + "close-board-pop": "Моћи ћете да повратите списе притиском на дугме “Архив” са почетног заглавља.", + "close-card": "Затвори предмет", "color-black": "црна", "color-blue": "плава", - "color-crimson": "тамно-црвена", - "color-darkgreen": "тамно-зелена", + "color-crimson": "тамноцрвена", + "color-darkgreen": "тамнозелена", "color-gold": "златна", "color-gray": "сива", "color-green": "зелена", - "color-indigo": "индиго", - "color-lime": "креч", - "color-magenta": "пурпурно-црвена", - "color-mistyrose": "магловито роза", - "color-navy": "морнарско плава", + "color-indigo": "у боји индиго пресликача", + "color-lime": "пастелнозелена", + "color-magenta": "љубичасто-црвена", + "color-mistyrose": "прљаво роза", + "color-navy": "тамноплава", "color-orange": "наранџаста", - "color-paleturquoise": "бледо-зелена", - "color-peachpuff": "кајсија", + "color-paleturquoise": "бледозелена", + "color-peachpuff": "у боји кајсије", "color-pink": "пинк", - "color-plum": "шљива", + "color-plum": "модра", "color-purple": "љубичаста", "color-red": "црвена", - "color-saddlebrown": "кожно седло", + "color-saddlebrown": "у боји кестена", "color-silver": "сребрна", "color-sky": "небеско плава", - "color-slateblue": "загасито плава", + "color-slateblue": "загаситоплава", "color-white": "бела", "color-yellow": "жута", "unset-color": "Обриши подешавање", - "comments": "Comments", + "comments": "Ставови", "comment": "Изнеси мишљење", - "comment-placeholder": "Простор за изношење мишљења", - "comment-only": "Износи мишљење", - "comment-only-desc": "Може да изнесе мишљење само на картицама са задацима.", - "comment-delete": "Да ли сте сигурни да желите да уклоните изнешено мишљење?", + "comment-placeholder": "Место за расправу", + "comment-only": "Стручни саветник", + "comment-only-desc": "Једино може да учествује у расправи око одређеног предмета.", + "comment-delete": "Да ли сте сигурни да желите да повучете изнешено мишљење?", "deleteCommentPopup-title": "Повлачите мишљење?", - "no-comments": "Нико није дао мишљење", - "no-comments-desc": "Не може да види изнешена мишљења и догађаје.", - "worker": "Радник", - "worker-desc": "Може само да помера картице са задацима, додељује их себи и да даје мишљење. ", + "no-comments": "Посматрач", + "no-comments-desc": "Не може да види расправу и прати записник.", + "worker": "Приправник", + "worker-desc": "Може да ради помоћне послове - да премешта предмете, бирa оне које ће пратити и да учествује у расправи. ", "computer": "Рачунар", - "confirm-subtask-delete-popup": "Да ли сте сигурни да желите да избришете подзадатак?", - "confirm-checklist-delete-popup": "Да ли сте сигурни да желите да избришете овај списак за обавити?", - "subtaskDeletePopup-title": "Избрисаћете подзадатак?", - "checklistDeletePopup-title": "Избрисаћете списак за обавити?", - "copy-card-link-to-clipboard": "Причувај везу до картице у привременој меморији", - "copy-text-to-clipboard": "Причувај текст у привременој меморији", - "linkCardPopup-title": "Повежи картицу", + "confirm-subtask-delete-popup": "Да ли сте сигурни да желите да избришете овај издвојени посао?", + "confirm-checklist-delete-popup": "Да ли сте сигурни да желите да избришете ову предметну радњу?", + "subtaskDeletePopup-title": "Избрисаћете издвојени посао?", + "checklistDeletePopup-title": "Избрисаћете предметну радњу?", + "copy-card-link-to-clipboard": "Причувај везу на кратко", + "copy-text-to-clipboard": "Причувај текст на кратко", + "linkCardPopup-title": "Повежи предмет", "searchElementPopup-title": "Претрага", - "copyCardPopup-title": "Умножи картицу", - "copyManyCardsPopup-title": "Умножи предложак на више картица", - "copyManyCardsPopup-instructions": "Наслови и описи одредишних картица у следећем JSON облику", - "copyManyCardsPopup-format": "[ {\"наслов\": \"Наслов прве картице\", \"опис\":\"Опис прве картице\"}, {\"наслов\":\"Наслов друге картице\",\"опис\":\"Опис друге картице\"},{\"наслов\":\"Наслов последње картице\",\"опис\":\"Опис последње картице\"} ]", + "copyCardPopup-title": "Умножи предмет", + "copyManyCardsPopup-title": "Расади попуњен образац", + "copyManyCardsPopup-instructions": "Наслови и описи одредишних предмета треба да имају следећи JSON облик:", + "copyManyCardsPopup-format": "[ {\"наслов\": \"Наслов првог предмета\", \"опис\":\"Опис првог предмета\"}, {\"наслов\":\"Наслов другог предмета\",\"опис\":\"Опис другог предмета\"},{\"наслов\":\"Наслов последњег предмете\",\"опис\":\"Опис последњег предмета\"} ]", "create": "Уведи", - "createBoardPopup-title": "Уведи нову пословну књигу", - "chooseBoardSourcePopup-title": "Уведи пословну књигу", + "createBoardPopup-title": "Увод нових списа", + "createTemplateContainerPopup-title": "Додај сандук са предлошцима", + "chooseBoardSourcePopup-title": "Унеси спољне списе", "createLabelPopup-title": "Нова налепница", - "createCustomField": "Направи сасвим ново поље", - "createCustomFieldPopup-title": "Направи сасвим ново поље", + "createCustomField": "Нова рубрика", + "createCustomFieldPopup-title": "Нова рубрика", "current": "текуће", - "custom-field-delete-pop": "Опозив ове радње неће бити могућ. Овим се уклања ово сасвим ново поље из свих картица и уништива његова историја.", + "custom-field-delete-pop": "Опозив ове радње неће бити могућ. Радњом се уклања ова придружена рубрика из свих предмета и уништива њена претходна историја употребе.", "custom-field-checkbox": "Поље за штиклирање", "custom-field-currency": "Валута", "custom-field-currency-option": "Код валуте", @@ -352,12 +367,16 @@ "custom-field-dropdown-unknown": "(непознато)", "custom-field-number": "Број", "custom-field-text": "Текст", - "custom-fields": "Сасвим нова поља", + "custom-fields": "Придружене рубрике", "date": "Датум", + "date-format": "Начин записивање датума", + "date-format-yyyy-mm-dd": "година-месец-дан", + "date-format-dd-mm-yyyy": "дан-месец-година", + "date-format-mm-dd-yyyy": "месец-дан-година", "decline": "Одбиј", - "default-avatar": "Унапред изабрана сличица", + "default-avatar": "иницијали уместо слике", "delete": "Уклони", - "deleteCustomFieldPopup-title": "Обрисаћете сасвим ново поље?", + "deleteCustomFieldPopup-title": "Обрисаћете ову придружену рубрику?", "deleteLabelPopup-title": "Одлепићете све овакве налепнице?", "description": "Опис", "disambiguateMultiLabelPopup-title": "Недвосмислене радње на налепницама", @@ -367,121 +386,122 @@ "download": "Преузми", "edit": "Уреди", "edit-avatar": "Моја слика", - "edit-profile": "Моји лични подаци", - "edit-wip-limit": "Уреди ограничење броја послова", - "soft-wip-limit": "Мека граница броја послова", - "editCardStartDatePopup-title": "Кад је задатак започет", - "editCardDueDatePopup-title": "Крајњи рок за испуњење задатка", - "editCustomFieldPopup-title": "Измени поље", + "edit-profile": "Лични подаци", + "edit-wip-limit": "Затрпавање предметима", + "soft-wip-limit": "Мека граница броја предмета", + "editCardStartDatePopup-title": "Кад сте започели рад на предмету", + "editCardDueDatePopup-title": "Крајњи рок за предмет", + "editCustomFieldPopup-title": "Измени наслов рубрике", "addReactionPopup-title": "Реакција на објаву", "editCardSpentTimePopup-title": "Промени утрошено време", "editLabelPopup-title": "Постојећа налепница", "editNotificationPopup-title": "Измени обавештење", "editProfilePopup-title": "Лични подаци", "email": "Е-пошта", + "email-address": "Адреса електронске поште", "email-enrollAccount-subject": "За Вас је направљен један налог на __siteName__", "email-enrollAccount-text": "Здраво __user__,\n\nДа би почели да користите услугу, једноставно притисните на везу која је испод.\n\n__url__\n\nХвала.", - "email-fail": "Неуспело слање е-поште", + "email-fail": "Неуспело слање е-поште!", "email-fail-text": "Грешка при покушају слања е-поште", "email-invalid": "Неисправна адреса е-поште", "email-invite": "Позив преко е-поште", "email-invite-subject": "__inviter__ Вам је послао позивницу", - "email-invite-text": "Драги __user__,\n\n__inviter__ Вас позива на заједничку сарадњу кроз \"__board__\" пословну књигу.\n\nМолим да испратите везу испод:\n\n__url__\n\nХвала.", + "email-invite-text": "Поштовани __user__,\n\n__inviter__ Вам је омогућио пун увид у \"__board__\" списе и нада се заједничкој сарадњи.\n\nМолим да испратите везу испод:\n\n__url__\n\nХвала.", "email-resetPassword-subject": "Задајте поново вашу лозинку на страници __siteName__", "email-resetPassword-text": "Добар дан __user__,\n\nДа би сте поново задали вашу лозинку, једноставно притисните на везу испод.\n\n__url__\n\nХвала.", "email-sent": "Е-пошта је послана", "email-verifyEmail-subject": "Потврдите Вашу адресу е-поште на страници __siteName__", "email-verifyEmail-text": "Добар дан __user__,\n\nДа би сте потврдили ваш налог за е-пошту, једноставно притисните на везу испод.\n\n__url__\n\nХвала.", "enable-vertical-scrollbars": "Enable vertical scrollbars", - "enable-wip-limit": "Ограничи број послова", - "error-board-doesNotExist": "Ова пословна књига не постоји", - "error-board-notAdmin": "Да би то урадили, треба да будете администратор/управник ове књиге пословања", - "error-board-notAMember": "Да би то урадили треба да будете сарадник у овој пословној књизи", + "enable-wip-limit": "Ограничи број предмета", + "error-board-doesNotExist": "Овакви списи не постоје", + "error-board-notAdmin": "Да би то урадили, треба да будете управник ових списа", + "error-board-notAMember": "Да би то урадили треба да будете сарадник на овим списима", "error-json-malformed": "То што сте укуцали нема исправан JSON облик", "error-json-schema": "Ваши подаци у JSON облику не укључују исправне информације у предвиђеном облику", "error-csv-schema": "Ваш CSV(Вредности раздвојене зарезом)/TSV (Вредности раздвојене табулатором) не укључује исправну информацију у предвиђеном облику", "error-list-doesNotExist": "Ова деоница не постоји", "error-user-doesNotExist": "Сарадник не постоји", - "error-user-notAllowSelf": "Не можеш да позовеш сам себе", - "error-user-notCreated": "Сарадник не постоји", - "error-username-taken": "Корисничко име је већ у употреби", - "error-orgname-taken": "Ово име предузећа је већ у употреби", - "error-teamname-taken": "Ово име тима је већ у употреби", + "error-user-notAllowSelf": "Не можете сами себе да позовете", + "error-user-notCreated": "Сарадник није уписан", + "error-username-taken": "Кориснички налог је већ у употреби", + "error-orgname-taken": "Ово (пословно) име странке је већ у употреби", + "error-teamname-taken": "Ово име правног тима је већ у употреби", "error-email-taken": "Ова адреса е-поште је већ у употреби", - "export-board": "Преведи пословну књигу", - "export-board-json": "Преведи пословну књигу у JSON", - "export-board-csv": "Преведи пословну књигу у CSV", - "export-board-tsv": "Преведи пословну књигу у TSV", - "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": "Превођење картице са задатком", + "export-board": "Претвори списе", + "export-board-json": "Претварање списа у JSON", + "export-board-csv": "Претварање списа у CSV", + "export-board-tsv": "Претварање списа у TSV", + "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": "Редослед", "sorted": "Сложено", - "remove-sort": "Разбацај", - "sort-desc": "Притисните да би сложили деонице", - "list-sort-by": "Поређај деоницу по:", - "list-label-modifiedAt": "Време последње измене", - "list-label-title": "Назив деонице", - "list-label-sort": "Vaš ručni nalog", - "list-label-short-modifiedAt": "(P)", - "list-label-short-title": "(N)", - "list-label-short-sort": "(R)", + "remove-sort": "Измешај предмете", + "sort-desc": "Притисните да би сложили делове поступка", + "list-sort-by": "Поређај делове поступка по:", + "list-label-modifiedAt": "Времену последње измене", + "list-label-title": "Називу дела поступка", + "list-label-sort": "Вашем личном нахођењу", + "list-label-short-modifiedAt": "(П)", + "list-label-short-title": "(Н)", + "list-label-short-sort": "(Л)", "filter": "Издвајање", - "filter-cards": "Издвој картице или деонице", + "filter-cards": "Издвој предмете или делове поступка", "filter-dates-label": "Издвој по датуму", - "filter-no-due-date": "Нема датума истека", - "filter-overdue": "Прекорачено време", - "filter-due-today": "Рок истиче данас", - "filter-due-this-week": "Рок истиче ове недеље", - "filter-due-next-week": "Рок истиче следеће недеље", - "filter-due-tomorrow": "Рок истиче сутрадан", - "list-filter-label": "Издвој деонице по наслову", + "filter-no-due-date": "Где није постављен рок", + "filter-overdue": "Где је пробијен рок", + "filter-due-today": "Где рок истиче данас", + "filter-due-this-week": "Где рок истиче ове недеље", + "filter-due-next-week": "Где рок истиче следеће недеље", + "filter-due-tomorrow": "Где рок истиче сутрадан", + "list-filter-label": "Издвој део поступка по наслову", "filter-clear": "Прекини са издвајањем", "filter-labels-label": "Издвој по налепници", "filter-no-label": "Нема налепницу", - "filter-member-label": "Издвој по сараднику", - "filter-no-member": "Нема сарадника", - "filter-assignee-label": "Издвој по задужењу", - "filter-no-assignee": "Нико није задужен", - "filter-custom-fields-label": "Издвој по сасвим новим пољима", - "filter-no-custom-fields": "Нема сасвим нових поља", - "filter-show-archive": "Прикажи архивиране деонице", - "filter-hide-empty": "Сакриј празне деонице", + "filter-member-label": "Издвој по надлежном сараднику", + "filter-no-member": "Нико није надлежан", + "filter-assignee-label": "Издвој по пуномоћнику", + "filter-no-assignee": "Где никоме није дата пуномоћ", + "filter-custom-fields-label": "Издвој по рубрикама", + "filter-no-custom-fields": "Где нема рубрика", + "filter-show-archive": "Прикажи архивиране делове поступка", + "filter-hide-empty": "Сакриј делове поступка без предмета", "filter-on": "Издваја се", - "filter-on-desc": "Издвајате картице из ове пословне књиге. Притисните овде да одредите како се издвајање врши.", + "filter-on-desc": "Сад издвајате предмете из ових списа. Притисните овде да одредите како се издвајање врши.", "filter-to-selection": "Издвајање по изабраном", - "other-filters-label": "Другачије издвајање", + "other-filters-label": "Преостала издвајања", "advanced-filter-label": "Напредно издвајање", - "advanced-filter-description": "Напредно издвајање Вам омогућава да напишете ниску која садржи следеће оператореAdvanced: == != <= >= && || ( ) Празно место се користи да раздвоји операторе. Можете да издвајате сва поља која сте измислили пишући њихова имена и вредности. На пример: ИмеИзмишљеногПоља == Вредност. Напомена: Уколико предметна поља или њихове вредности садрже празна места треба да их обухватите у једноструке наводнике. На пример: 'Поље 1' == 'Вредност 1'. Да би избегли контролне знаке (' \\\\/) , можете да користите \\\\. Например: Поље1 == Ал\\\\' је дугачко поље. Такође можете измешати више услова. На пример: Поље1 == Вредност1 || Поље1 == Вредност2. Провера услова се обавља са лева на десно. Додавањем заграда ћете утицати на проверу. На пример: Поље1 == Вредност1 && ( Поље2 == Вредност2 || Поље2 == Вредност3 ). Такође можете претраживати поља програмерским изразима: Поље1 == /Tes.*/i", + "advanced-filter-description": "Напредно издвајање Вам омогућава да напишете ниску која садржи следеће операторе: == != <= >= && || ( ) Размак се користи да раздвоји операторе. Можете да издвајате поља из придружених рубрика позивајући се на њихова имена и вредности. На пример: ИмеПридруженогПоља == Вредност. Напомена: Уколико предметна поља или њихове вредности садрже размак треба да га обухватите у једноструке наводнике. На пример: 'Поље 1' == 'Вредност 1'. Да би избегли контролне знаке (' \\\\/) , можете да користите \\\\. Например: Поље1 == I\\\\'m . Такође можете измешати више услова. На пример: Поље1 == Вредност1 || Поље1 == Вредност2. Провера услова се обавља са лева на десно. Додавањем заграда ћете утицати на проверу. На пример: Поље1 == Вредност1 && ( Поље2 == Вредност2 || Поље2 == Вредност3 ). Такође можете претраживати поља програмерским изразима: Поље1 == /Tes.*/i", "fullname": "Име и презиме", - "header-logo-title": "Вратите се на полицу са Вашим пословним књигама.", - "show-activities": "Show Activities", - "headerBarCreateBoardPopup-title": "Отвори нову књигу пословања", + "header-logo-title": "Вратите се на полицу са Вашим списима.", + "show-activities": "Писани записник", + "headerBarCreateBoardPopup-title": "Увод нових списа", "home": "Почетна", "import": "Унеси", - "impersonate-user": "Лажно представљен корисник", + "impersonate-user": "Увуци се у налог овог корисника", "link": "Веза", - "import-board": "уведи пословну књигу", - "import-board-c": "Уведи пословну књигу", - "import-board-title-trello": "Уведи књигу пословања из Trella", - "import-board-title-wekan": "Уведи пословну књигу из претходног преноса", - "import-board-title-csv": "Уведи једну CSV/TSV пословну књигу", - "from-trello": "Из Trello", - "from-wekan": "Из претходног превода", - "from-csv": "Из CSV/TSV", - "import-board-instruction-trello": "У Вашој Trello пословној књизи, идите у 'Menu', затим 'More', 'Print and Export', 'Export JSON', и умножите представљени текст.", + "import-board": "унеси спољне списе", + "import-board-c": "Извор спољних списа", + "import-board-title-trello": "Trello", + "import-board-title-wekan": "Wekan", + "import-board-title-csv": "CSV/TSV", + "from-trello": "Извор Trello", + "from-wekan": "Извор претходни Wekan подаци", + "from-csv": "Извор CSV/TSV датотека", + "import-board-instruction-trello": "У Вашоим Trello списима, идите у 'Menu', затим 'More', 'Print and Export', 'Export JSON', и умножите представљени текст.", "import-board-instruction-csv": "Овде залепите Ваше CSV податке (вредности раздвојене зарезом) односно TSV податке (вредности раздвојене табулатором) .", - "import-board-instruction-wekan": "У Вашој књизи пословања, изаберите ставке 'Мени', затим 'Преведи пословни књигу' и на крају умножите сав садржај/текст из преузете датотеке.", - "import-board-instruction-about-errors": "Ако се јаве грешке при уношење пословне књиге то не значи да унос није успео!Проверите јел се књига појавила у одељку Моје пословне књиге.", + "import-board-instruction-wekan": "У Вашим списима, изаберите ставке 'Мени', затим 'Унеси списе' и на крају умножите сав садржај/текст из преузете датотеке.", + "import-board-instruction-about-errors": "Ако се јаве грешке при уношењу списа то не значи да унос није успео!Проверите јел се спис појавио у одељку „Списи у мојој надлежности“.", "import-json-placeholder": "Овде сместите Ваше исправне JSON податке", "import-csv-placeholder": "Овде сместите Ваше исправне CSV/TSV податке", "import-map-members": "Мапирај сараднике", - "import-members-map": "Пословна књига коју сте унели има постављену мрежу сарадника. Молим да мапирате сараднике из те мреже на Ваше сараднике", + "import-members-map": "Списи које сте унели имају постављену мрежу сарадника. Молим да мапирате сараднике из те мреже на Ваше сараднике", "import-members-map-note": "Белешка: Немапирани сарадници ће бити додељени на тренутног корисника.", "import-show-user-mapping": "Испрегледај како су сарадници измапирани", "import-user-select": "Изаберите Вашег познатог сарадника којег желите да корисите као овог", @@ -492,68 +512,68 @@ "invalid-time": "Нетачно време", "invalid-user": "Непознат корисник", "joined": "придружен", - "just-invited": "Управо сте позвани у ову књигу пословања", + "just-invited": "Управо сте позвани да радите на овим списима", "keyboard-shortcuts": "Пречице на тастатури", "label-create": "Уведи нову налепницу", "label-default": "%s налепница (подразумевано)", - "label-delete-pop": "Пажња. Опозив ове радње неће бити могућ! Изабрана налепница ће бити одлепљена/уклоњена са свих картица са задацима и њена историја ће исчезнути.", + "label-delete-pop": "Пажња. Опозив ове радње неће бити могућ! Изабрана налепница ће бити одлепљена/уклоњена из свих предмета и њена историја ће исчезнути.", "labels": "Налепнице", "language": "Језик", "last-admin-desc": "Не можете да мењате задужења јер мора постојати барем један управник/администратор.", - "leave-board": "Раздужи књигу пословања", - "leave-board-pop": "Да ли сте сигурни да желите да раздужите пословну књигу __boardTitle__? Бићете одстрањени са свих задатака из ове књиге пословања.", - "leaveBoardPopup-title": "Раздужићете пословну књигу ?", - "link-card": "Веза до ове картице", - "list-archive-cards": "Премести у архив све картице са задацима са ове деонице", - "list-archive-cards-pop": "Овим склањате све задатке на овој деоници из књиге пословања. Да испрегледате архивиране задатке и вратите их натраг у књигу пословања притисните на “Мени” > “Архив”.", - "list-move-cards": "Премести све картице на овој деоници", - "list-select-cards": "Изабери све картице на овој деоници", - "set-color-list": "Обоји деоницу", - "listActionPopup-title": "Радње на деоници", - "settingsUserPopup-title": "Корисничка подешавања", - "settingsTeamPopup-title": "Тимска подешавања", - "settingsOrgPopup-title": "Подешавања предузећа", - "swimlaneActionPopup-title": "Радње на стазама", - "swimlaneAddPopup-title": "Додаје једну стазу испод", - "listImportCardPopup-title": "Унеси једну Trello картицу", + "leave-board": "Раздужи предмете из списа", + "leave-board-pop": "Да ли сте сигурни да желите да раздужите предмете из списа __boardTitle__? Бићете одстрањени са свих тих предмета.", + "leaveBoardPopup-title": "Раздужићете списе ?", + "link-card": "Повежи предмете", + "list-archive-cards": "Архивирај све предмете из овог дела", + "list-archive-cards-pop": "Овим склањате све предмете из овог дела поступка из списа. Да испрегледате тако архивиране предмете и вратите их натраг у ове списе притисните на “Мени” > “Архива”.", + "list-move-cards": "Премести све предмете из овог дела поступка", + "list-select-cards": "Изабери све предмете", + "set-color-list": "Обоји", + "listActionPopup-title": "Радње у делу поступка", + "settingsUserPopup-title": "Рад са сарадницима", + "settingsTeamPopup-title": "Рад са правним тимовима", + "settingsOrgPopup-title": "Рад са странкама", + "swimlaneActionPopup-title": "Радње у овој врсти поступка", + "swimlaneAddPopup-title": "Додаје испод врсту поступка", + "listImportCardPopup-title": "Унеси једнан Trello предмет", "listImportCardsTsvPopup-title": "Унеси Excel CSV/TSV", "listMorePopup-title": "Више", "link-list": "Веза до ове деонице", - "list-delete-pop": "Све досадашње забележене радње на деоници биће уклоњене и нећете моћи опоравити деоницу. Опозив ове радње неће бити могућ.", - "list-delete-suggest-archive": "Можете да преместите целу неку деоницу у Архив чиме чувате историју деонице а ипак је склањате из књиге пословања.", - "lists": "Деонице", - "swimlanes": "Стазе", - "log-out": "Одјава", + "list-delete-pop": "Читав записник са овог дела поступка биће уклоњен и нећете га моћи опоравити. Опозив ове радње неће бити могућ.", + "list-delete-suggest-archive": "Боље је да преместите читав део поступка у Архив чиме чувате записник а део поступка ипак склањате из списа.", + "lists": "Делови поступка", + "swimlanes": "Врсте поступака", + "log-out": "Одјави се", "log-in": "Пријави се", - "loginPopup-title": "Пријава", + "loginPopup-title": "Пријавница", "memberMenuPopup-title": "Сарадник", "members": "Сарадници", "menu": "Мени", "move-selection": "Премести изабрано", - "moveCardPopup-title": "Премести картицу са задатком", + "moveCardPopup-title": "Премести предмет", "moveCardToBottom-title": "Премести на дно", "moveCardToTop-title": "Премести на врх", "moveSelectionPopup-title": "Премести изабрано", "multi-selection": "Вишеструк избор", - "multi-selection-label": "Изаберите налепницу", - "multi-selection-member": "Изаберите и сарадника", - "multi-selection-on": "Вишеструк избор је омогућен", - "muted": "Утишано", - "muted-info": "Нећете чути обавештење о променама у овој пословној књизи", - "my-boards": "Моје књиге пословања", + "multi-selection-label": "Залепите или одлепите налепнице на одабране предмете", + "multi-selection-member": "Одаберите и сараднике", + "multi-selection-on": "Постоји вишеструк избор", + "muted": "Не примај обававештења", + "muted-info": "Нећете чути обавештења кад наступе било какве промене у овим списима", + "my-boards": "Списи у мојој надлежности", "name": "Задајте (нови) натпис", - "no-archived-cards": "Нама архивираних картица са задацима.", - "no-archived-lists": "Нема архивираних деоница.", - "no-archived-swimlanes": "Нема архивираних стаза.", + "no-archived-cards": "Нема архивираних предмета.", + "no-archived-lists": "Нема архивираних делова поступака.", + "no-archived-swimlanes": "Нема архивираних врсти поступака.", "no-results": "Нема резултата", - "normal": "Нормално", - "normal-desc": "Може да гледа и уређује картице. Не може да мења подешавања.", + "normal": "Виши сарадник", + "normal-desc": "Може да има и увид и пун приступ предметима. Не може да поставља правила рада на списима.", "not-accepted-yet": "Позив још није прихваћен", - "notify-participate": "Примајте допунске извештаје за било које картице са задацима у којима учествујете као налогодавац или сарадник", - "notify-watch": "Примајте допунске извештаје за било које пословне књиге, деонице, или картице са задацима које пратите", + "notify-participate": "Примајте допунске извештаје при било којој измени предмета које сте сами завели или где сте сарадник", + "notify-watch": "Примајте допунске извештаје при било којој измени списа, делова поступака или предмета које пратите", "optional": "по избору", "or": "или", - "page-maybe-private": "Ова страницаје је, могуће, приватна. Можда ћете моћи да је видите кад се пријавите.", + "page-maybe-private": "Ови списи су могуће под велом тајности. Можда ћете ипак моћи да их видите кад се пријавите овде.", "page-not-found": "Страница није пронађена.", "password": "Лозинка", "paste-or-dragdrop": "налепи, или држи и испусти слику на то (важи само за слике)", @@ -561,114 +581,114 @@ "preview": "Приказ", "previewAttachedImagePopup-title": "Приказ", "previewClipboardImagePopup-title": "Приказ", - "private": "Приватно", - "private-desc": "Ова пословна књига је приватна. Само одобрени сарадници могу да је читају и уређују.", + "private": "Видљиво сарадницима", + "private-desc": "Ови списи су тајни. Само одобрени сарадници могу да их читају и уређују.", "profile": "Особина", - "public": "Јавно", - "public-desc": "Ова пословна књига је јавна. Видљива је сваком ко има везу и појавиће се у google претрагама. Једино одобрени сарадници могу бити уредници.", - "quick-access-description": "Означи књигу пословања звездицом да додаш пречицу на ову траку.", - "remove-cover": "Уклоните насловну слику са мини картице", - "remove-from-board": "Избаци из књиге пословања", + "public": "Списи видљиви свима", + "public-desc": "Ови списи су потпуно јавни. Видљиви су сваком ко има везу до њих и појавиће се и у google претрагама. Једино одобрени сарадници могу бити уредници.", + "quick-access-description": "Означите списе звездицом да би додали пречицу на ову траку.", + "remove-cover": "Уклоните осликани омот", + "remove-from-board": "Избаци из списа", "remove-label": "Скини налепницу", - "listDeletePopup-title": "Обрисаћете деоницу?", - "remove-member": "Удаљи сарадника", - "remove-member-from-card": "Удаљи га са задатка", - "remove-member-pop": "Удаљићете __name__ (__username__) из __boardTitle__? Сарадник ће бити удаљен са свих задатака из ове књиге пословања. Примиће обавештење о томе.", - "removeMemberPopup-title": "Удаљићете сарадника?", + "listDeletePopup-title": "Обрисаћете део поступка?", + "remove-member": "Скини сарадника", + "remove-member-from-card": "Скини га са предмета", + "remove-member-pop": "Изузећете __name__ (__username__) из списа __boardTitle__? Сарадник ће бити изузет са свих предмета у списима. Примиће обавештење о томе.", + "removeMemberPopup-title": "Изузећете сарадника?", "rename": "Преименуј", - "rename-board": "Преименуј књигу пословања", + "rename-board": "Преименуј списе", "restore": "Опорави", - "rescue-card-description": "Понуди још једну прилику да се забележе несачувани описи задатака пре затварања картице", - "rescue-card-description-dialogue": "Преписаћете тренутни опис задатка са Вашим описом?", + "rescue-card-description": "Понуди још једну прилику да се забележи несачувани опис предмета пре затварања", + "rescue-card-description-dialogue": "Преписаћете тренутни опис предмета са допуњеним?", "save": "Сачувај", "search": "Претрага", - "rules": "Правила", - "search-cards": "Тражи у насловима задатака/деоница, новим пољима у овој пословној књизи", - "search-example": "Укуцајте речи/текст које тражите и притисните ентер", - "select-color": "Изаберите (нову) боју", - "select-board": "Изаберите књигу пословања", - "set-wip-limit-value": "Поставите границу за максимални дозвољени број задатака на овој деоници", - "setWipLimitPopup-title": "Поставите ограничење броја послова", - "shortcut-add-self": "Add yourself to current card", - "shortcut-assign-self": "Придружите себе тренутној картици", + "rules": "Правилник", + "search-cards": "Тражи у насловима предмета, делова поступака и рубрика у овим списима", + "search-example": "Укуцајте све што тражите и притисните ентер", + "select-color": "Изабери боју за овакав поступак", + "select-board": "Изаберите списе", + "set-wip-limit-value": "Поставите границу дозвољеног броја предмета у овом делу поступка", + "setWipLimitPopup-title": "Ограничење броја предмета", + "shortcut-add-self": "Доделите надлежност себи", + "shortcut-assign-self": "Поверите пуномоћ себи", "shortcut-autocomplete-emoji": "Сам попуни emoji", "shortcut-autocomplete-members": "Сам попуни сараднике", "shortcut-clear-filters": "Прекини издвајање", "shortcut-close-dialog": "Затвори прозорче", - "shortcut-filter-my-cards": "Издвој задатке", - "shortcut-filter-my-assigned-cards": "Filter my assigned cards", - "shortcut-show-shortcuts": "Прикажи овај списак пречица", - "shortcut-toggle-filterbar": "Укључи/искључи бочни мени за издвајање", - "shortcut-toggle-searchbar": "Укључи/искључи бочни мени за претрагу", - "shortcut-toggle-sidebar": "Укључи/искључи бочни мени пословне књиге", - "show-cards-minimum-count": "Прикажи број картица са задацима ако деоница садржи више од", - "sidebar-open": "Отвори бочну површину", - "sidebar-close": "Затвори бочну површину", - "signupPopup-title": "Направите налог", - "star-board-title": "Притисни да означиш звездицом баш ову књигу пословања. Имаће предност и бити на челу.", - "starred-boards": "Пословне књиге са звездицом", - "starred-boards-description": "Књиге пословања са звездицом се појављују испред других.", + "shortcut-filter-my-cards": "Издвој предмете где имам увид", + "shortcut-filter-my-assigned-cards": "Издвој предмете где сам пуномоћник", + "shortcut-show-shortcuts": "Прикажи овај подсетник са пречицама", + "shortcut-toggle-filterbar": "Алат за издвајање", + "shortcut-toggle-searchbar": "Алат за претрагу", + "shortcut-toggle-sidebar": "Алат за рад са списима", + "show-cards-minimum-count": "Изброј предмете и прикажи тај број тек ако део поступка садржи више од", + "sidebar-open": "Извади алат", + "sidebar-close": "Спакуј алат", + "signupPopup-title": "Јединствени регистар", + "star-board-title": "Означите спис звездицом. Имаће предност и бити на челу.", + "starred-boards": "Списи са звездицом", + "starred-boards-description": "Списи означени звездицом се појављују испред других.", "subscribe": "Претплати се", - "team": "Тим", - "this-board": "ова пословна књига", - "this-card": "ова картица са задатком", + "team": "Правни тим", + "this-board": "ове списе", + "this-card": "овај предмет", "spent-time-hours": "Потрошено време (у сатима)", "overtime-hours": "Прековремени (сати)", "overtime": "Прековремено", - "has-overtime-cards": "Има задатке на којима је прековремено радио", - "has-spenttime-cards": "Има задатке са мерењем времена", + "has-overtime-cards": "Постоје предмети са прековременим радом", + "has-spenttime-cards": "Постоје предмети где сат одбројава", "time": "Време", "title": "Наслов", - "toggle-assignees": "Toggle assignees 1-9 for card (By order of addition to board).", - "toggle-labels": "Укључи/искључи натписе од 1 до 9 за задатак. Вишеструк избор додаје натпис од 1 до 9", - "remove-labels-multiselect": "Вишеструким избором се уклањају натписи од 1 до 9", - "tracking": "Праћење", - "tracking-info": "Бићете обавештени о свим променама на оним картицама са задацима где сте укључени као налогодавац или као сарадник.", + "toggle-assignees": "Одабери пуномоћника на предмету по редоследу додавања у увид у списе.", + "toggle-labels": "Лепите и одлепљујете налепнице по броју. Вишеструким избором можете само да лепите", + "remove-labels-multiselect": "Вишеструким избором одлепљујете налепнице", + "tracking": "Прикупљај обавештења из моје надлежности", + "tracking-info": "Бићете обавештени о било каквој промени у оним предметима где сте укључени као сарадник или које сте лично завели.", "type": "Врста", "unassign-member": "Недодељени сарадник", "unsaved-description": "Нисте сачували опис.", "unwatch": "Скини са мера праћења", "upload": "Подигни", - "upload-avatar": "Пошаљите Вашу сличицу на сервер", - "uploaded-avatar": "Сличица је подигнута на сервер", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", - "custom-top-left-corner-logo-image-url": "Веза до места на Интернету где је слика са Вашим логом за приказивање у горњем левом углу", + "upload-avatar": "слика уместо иницијала", + "uploaded-avatar": "Слика је подигнута на сервер", + "uploading-files": "Шаљем датотеке", + "upload-failed": "Слање није успело", + "upload-completed": "Слање је успело", + "custom-top-left-corner-logo-image-url": "Веза до места на Интернету где се налази слика са Вашим логом за приказивање у горњем левом углу", "custom-top-left-corner-logo-link-url": "Веза до места на Интернету које се посећује када си кликне на Ваш лого у горњем левом углу", "custom-top-left-corner-logo-height": "Висина за Ваш лого у горњем левом углу. Уобичајена вредност: 27", - "custom-login-logo-image-url": "Веза до места на Интернету где је насловна слика код пријаве", + "custom-login-logo-image-url": "Веза до места на Интернету са ког се повлачи насловна слика код пријаве", "custom-login-logo-link-url": "Слика изнад дела за пријаву води до следећег места на Интернету", "custom-help-link-url": "Место на Интернету где се може затражити помоћ", "text-below-custom-login-logo": "Порука испод насловне слике на страни за пријаву", "automatic-linked-url-schemes": "Група места на Интернету која би могла да се посете. Једна група по линији", - "username": "Корисничко име", - "import-usernames": "Увези корисничка имена", + "username": "Кориснички налог", + "import-usernames": "Увези корисничке налоге", "view-it": "Погледај је", - "warn-list-archived": "упозорење: ова картица са задатком јесте у једној деоници али у архиви", - "watch": "Посматрај", - "watching": "Посматрање", - "watching-info": "Бићете обавештени о променама у овој пословној књизи", - "welcome-board": "Пословна књига за добродошлицу", - "welcome-swimlane": "Стаза 1", + "warn-list-archived": "упозорење: овај предмет постоји у архиви у једном делу поступка", + "watch": "Стави на мере праћења", + "watching": "Прикупљај сва обавештења", + "watching-info": "Бићете обавештени о било каквој промени у овим списима", + "welcome-board": "Списи са добродошлицом", + "welcome-swimlane": "Врста 1", "welcome-list1": "Основно", "welcome-list2": "Напредно", - "card-templates-swimlane": "Предлошци за картице са задацима", - "list-templates-swimlane": "Предложак за деонице", - "board-templates-swimlane": "Предложак за пословну књигу", + "card-templates-swimlane": "Обрасци за предмете", + "list-templates-swimlane": "Обрасци за делове поступака", + "board-templates-swimlane": "Обрасци за списе", "what-to-do": "Шта желите да урадите ?", - "wipLimitErrorPopup-title": "Досегнуто ограничење броја послова", - "wipLimitErrorPopup-dialog-pt1": "Број задатака на овој деоници је већи него ограничење које сте поставили.", - "wipLimitErrorPopup-dialog-pt2": "Молим да или обавите неке послове на овој деоници или да поставите веће ограничење дозвољеног броја послова.", - "admin-panel": "Главна управа", - "settings": "Подешавања", + "wipLimitErrorPopup-title": "Досегнуто ограничење броја предмета", + "wipLimitErrorPopup-dialog-pt1": "Број предмета у овом делу поступка је већи него ограничење које сте поставили.", + "wipLimitErrorPopup-dialog-pt2": "Молим да преместите неке предмете из овог дела поступка или да повећате границу.", + "admin-panel": "Управа", + "settings": "Општа поставка", "people": "Сарадници", - "registration": "Отварање налога", - "disable-self-registration": "Онемогући да корисници сами себи отворе налог", - "disable-forgot-password": "Онемогући да корисници сами затраже промену лозинке", - "invite": "Позив", - "invite-people": "Позови сараднике", - "to-boards": "У пословну књигу(e)", + "registration": "Упис", + "disable-self-registration": "Налог не може да се отвори без позивнице", + "disable-forgot-password": "Спречи процедуру за заборављену лозинку", + "invite": "Упути позив", + "invite-people": "Доле позваним омогући и пун увид", + "to-boards": "У списе", "email-addresses": "Адресе е-поште", "smtp-host-description": "Тачна адреса SMTP сервера који рукује вашом е-поштом.", "smtp-port-description": "Порт Вашег SMTP сервера који се користи за одлазну е-пошту.", @@ -679,23 +699,23 @@ "smtp-password": "Лозинка", "smtp-tls": "TLS подршка", "send-from": "Од", - "send-smtp-test": "Пошаљите сами себи једну пробну е-поруку", + "send-smtp-test": "Проба да ли поруке пролазе", "invitation-code": "Позивни код", "email-invite-register-subject": "__inviter__ Вам је послао позивницу", - "email-invite-register-text": "Драги __user__,\n\n__inviter__ Вас позива да користите kanban пословне књиге за заједнички рад.\n\nМолим испратите везу испод:\n__url__\n\nИ да, Ваш позивни код је: __icode__\n\nХвала.", + "email-invite-register-text": "Поштовани __user__,\n\n__inviter__ Вас позива да користите kanban списе за заједнички рад.\n\nМолим испратите везу испод:\n__url__\n\nИ да, Ваш позивни код је: __icode__\n\nХвала.", "email-smtp-test-subject": "Проба да ли ради слање е-поште", "email-smtp-test-text": "Успешно сте послали е-пошту", - "error-invitation-code-not-exist": "Позивни код не постоји", + "error-invitation-code-not-exist": "Такав позивни код не постоји", "error-notAuthorized": "Немате права да приступате овој страници.", - "webhook-title": "Назив мрежне куке", + "webhook-title": "Назив за дојаву догађаја", "webhook-token": "Token (необавезно за проверу идентитета)", - "outgoing-webhooks": "Одлазна мрежна кука", - "bidirectional-webhooks": "Двосмерне мрежне куке", - "outgoingWebhooksPopup-title": "Одлазне мрежне куке", + "outgoing-webhooks": "Дојава догађаја", + "bidirectional-webhooks": "Двосмерно понашање", + "outgoingWebhooksPopup-title": "Дојава догађаја", "boardCardTitlePopup-title": "Издвајање по наслову задатка", - "disable-webhook": "Онеспособи ову мрежну куку", - "global-webhook": "Глобална мрежна кука", - "new-outgoing-webhook": "Нова одлазна мрежна кука", + "disable-webhook": "Онеспособи ову дојаву догађаја", + "global-webhook": "Дојава догађаја", + "new-outgoing-webhook": "Нова дојава догађаја", "no-name": "(непознато)", "Node_version": "Node верзија", "Meteor_version": "Meteor верзија", @@ -715,76 +735,78 @@ "hours": "сати", "minutes": "минута", "seconds": "секунди", - "show-field-on-card": "Прикажи ово поље на картицу са задатком", - "automatically-field-on-card": "Придодај поље новим картицама", - "always-field-on-card": "Придодај поље свим картицама", - "showLabel-field-on-card": "Прикажи натпис на налепници", - "showSum-field-on-list": "Прикажи збирни број поља на врху деонице", + "show-field-on-card": "Придружи ову рубрику овом предмету", + "automatically-field-on-card": "Сви будући предмети ће имати овакву рубрику", + "always-field-on-card": "Придодај овакву рубрику и свим постојећим предметима", + "showLabel-field-on-card": "Прикажи натпис ове рубрике на омоту предмета", + "showSum-field-on-list": "Прикажи збирни број придружених рубрика на врху деонице", "yes": "Да", "no": "Не", "accounts": "Налози", "accounts-allowEmailChange": "Дозволи промену адресе е-поште", - "accounts-allowUserNameChange": "Дозволи промену корисничког имена", - "tableVisibilityMode-allowPrivateOnly": "Видљивост пословне књиге: Дозволи једино приватне пословне књиге", - "tableVisibilityMode" : "Видљивост пословне књиге", + "accounts-allowUserNameChange": "Дозволи промену имена налога", + "tableVisibilityMode-allowPrivateOnly": "Тајност списа: Дозволи приступ искључиво затвореном кругу сарадника", + "tableVisibilityMode" : "Тајност списа", "createdAt": "Направљено дана", "modifiedAt": "Време измене", - "verified": "Потрврђено", + "verified": "Потврђен налог", "active": "На окупу", - "card-received": "Пријем", - "card-received-on": "Примљен дана", - "card-end": "Завршетак", - "card-end-on": "Завршава се дана", - "editCardReceivedDatePopup-title": "Датум и време запримања задатка", - "editCardEndDatePopup-title": "Кад је задатак постао испуњен", - "setCardColorPopup-title": "Обоји картицу", - "setCardActionsColorPopup-title": "Изабери боју", - "setSwimlaneColorPopup-title": "Изабери боју стазе", - "setListColorPopup-title": "Изабери боју деонице", - "assigned-by": "Додељено од стране", + "card-received": "Запримљен", + "card-received-on": "Предмет запримљен дана", + "card-end": "Окончан", + "card-end-on": "Предмет окончан дана", + "editCardReceivedDatePopup-title": "Датум и време запримања предмета", + "editCardEndDatePopup-title": "Кад је задатак окончан", + "setCardColorPopup-title": "Боја омота предмета", + "setCardActionsColorPopup-title": "Боја за подлогу предмета", + "setSwimlaneColorPopup-title": "Боја за врсту поступка", + "setListColorPopup-title": "Боја за део поступка", + "assigned-by": "Властодавац", "requested-by": "Захтевано од", - "card-sorting-by-number": "Пресложи картице по броју", - "board-delete-notice": "Избацивање је трајно. Изгубићете све деонице, картице са задацима и радње повезане са овом књигом пословања.", - "delete-board-confirm-popup": "Све деонице, картице са задацима, налепнице и радње биће избачене и нећете моћи да повратите садржај књиге пословања. Опозив ове радње неће бити могућ.", - "boardDeletePopup-title": "Избацићете пословну књигу?", - "delete-board": "Избаци пословну књигу", - "default-subtasks-board": "Под задаци за __board__ књигу пословања", + "card-sorting-by-number": "Бројчана ознака за редослед", + "board-delete-notice": "Избацивање је трајно. Изгубићете све делове поступка, предмете и радње повезане са овим списима.", + "delete-board-confirm-popup": "Сви делови поступка, предмети, налепнице и записници биће избачени и нећете моћи да повратите садржај списа. Опозив ове радње неће бити могућ.", + "boardDeletePopup-title": "Избацићете ове списе?", + "delete-board": "Избаци списе", + "delete-duplicate-lists": "Уклоните истоимене делове поступка", + "delete-duplicate-lists-confirm": "Да ли сте сигурни? Овом радњом ће бити избрисани сви истоимени делови поступка где нема предмета.", + "default-subtasks-board": "Утврђени пријемни списи __board__", "default": "Подразумевано", "defaultdefault": "Подразумевано", - "queue": "Ред", - "subtask-settings": "Подешавања подзадатака", - "card-settings": "Подешавања картице са задацима", - "minicard-settings": "Подешавања малих картица", - "boardSubtaskSettingsPopup-title": "Подешавања под задатака у пословним књигама", - "boardCardSettingsPopup-title": "Подешавања картица са задацима", - "boardMinicardSettingsPopup-title": "Подешавања малих картица", - "deposit-subtasks-board": "Депонуј подзадатке у ову пословну књигу:", - "deposit-subtasks-list": "Деоница у којој се смештају под задаци овде депоновани:", - "show-parent-in-minicard": "Прикажи порекло у малој картици:", - "description-on-minicard": "Опис мале картице", - "cover-attachment-on-minicard": "Насловна слика на мини картици", - "badge-attachment-on-minicard": "Број прилога на мини картици", - "card-sorting-by-number-on-minicard": "Слагање картица по броју на мини картици", - "prefix-with-full-path": "Префикс са пуном путањом", - "prefix-with-parent": "Префикс са пореклом", - "subtext-with-full-path": "Subtext са пуном путањом", - "subtext-with-parent": "Subtext са пореклом", - "change-card-parent": "Промени порекло картице", - "parent-card": "Родитељска картица", - "source-board": "Изворна књига пословања", - "no-parent": "Не приказуј порекло", + "queue": "Пријемно одељење", + "subtask-settings": "Поставка издвојених послова", + "card-settings": "Појединости и омот предмета", + "minicard-settings": "Рад са омотима предмета", + "boardSubtaskSettingsPopup-title": "Руковање издвојеним пословима", + "boardCardSettingsPopup-title": "Предмети у списима", + "boardMinicardSettingsPopup-title": "Рад са омотима предмета", + "deposit-subtasks-board": "Депонуј издвојене послове у списе:", + "deposit-subtasks-list": "Пријемно одељење кад овде депонују:", + "show-parent-in-minicard": "Испис порекла на омоту предмета:", + "description-on-minicard": "Опис на омоту", + "cover-attachment-on-minicard": "Мотив из предметне грађе", + "badge-attachment-on-minicard": "Број поред спајалице", + "card-sorting-by-number-on-minicard": "Бројчана ознака за редослед", + "prefix-with-full-path": "Испиши пуну путању као уводни слог", + "prefix-with-parent": "Испиши порекло као уводни слог", + "subtext-with-full-path": "Испиши пуну путању испод ситним словима", + "subtext-with-parent": "Испиши порекло испод ситним словима", + "change-card-parent": "Промени порекло предмета", + "parent-card": "Родитељски предмет", + "source-board": "Изворни списи", + "no-parent": "Немој исписивати никакво порекло", "activity-added-label": "залепљена налепница '%s' на %s", "activity-removed-label": "уклоњена је налепница '%s' са %s", "activity-delete-attach": "уклоњен је прилог са %s", "activity-added-label-card": "залепљена је налепница '%s'", "activity-removed-label-card": "уклоњена је налепница '%s'", "activity-delete-attach-card": "избрисан је прилог", - "activity-set-customfield": "постављено је сасвим ново поље '%s' на '%s' у %s", - "activity-unset-customfield": "уклоњено је сасвим ново поље '%s' у %s", + "activity-set-customfield": "придружена је рубрика '%s' на '%s' у %s", + "activity-unset-customfield": "уклоњена је рубрика '%s' у %s", "r-rule": "Правило", - "r-add-trigger": "Додај окидач", - "r-add-action": "Додај радњу", - "r-board-rules": "Правила пословне књиге", + "r-add-trigger": "Прво додајте догађај", + "r-add-action": "Затим додајте радњу као одговор", + "r-board-rules": "Списак правила", "r-add-rule": "Додај правило", "r-view-rule": "Прегледај правило", "r-delete-rule": "Обриши правило", @@ -792,104 +814,104 @@ "r-no-rules": "Није уведено правило", "r-trigger": "Окидач", "r-action": "Радња", - "r-when-a-card": "Када картица", + "r-when-a-card": "Предмет", "r-is": "је", - "r-is-moved": "је премештена", - "r-added-to": "Додан у", - "r-removed-from": "Уклоњена из", - "r-the-board": "пословна књига", - "r-list": "деоница", + "r-is-moved": "премештен", + "r-added-to": "додана на", + "r-removed-from": "скинут са", + "r-the-board": "списа", + "r-list": "део", "set-filter": "Правило издвајања", - "r-moved-to": "Премештен у", - "r-moved-from": "Премештен из", + "r-moved-to": "премештен у", + "r-moved-from": "премештен из", "r-archived": "Премештен у архиву", "r-unarchived": "Извучен из архиве", - "r-a-card": "једна картица са задатком", - "r-when-a-label-is": "Када је налепница", - "r-when-the-label": "Када налепница", - "r-list-name": "име деонице", - "r-when-a-member": "Када је сарадник", - "r-when-the-member": "Када сарадник", + "r-a-card": "предмет", + "r-when-a-label-is": "Када је било која налепница", + "r-when-the-label": "Налепница", + "r-list-name": "име дела поступка", + "r-when-a-member": "Када је било који сарадник", + "r-when-the-member": "Сарадник по имену", "r-name": "име", - "r-when-a-attach": "Када је додатак", - "r-when-a-checklist": "Када је списак за обавити", - "r-when-the-checklist": "Када списак за обавити", - "r-completed": "Обављен", - "r-made-incomplete": "Није обављен", - "r-when-a-item": "Када је ставка на списку за обавити", - "r-when-the-item": "Када ставка на списку за обавити", - "r-checked": "Обављена", - "r-unchecked": "Необављена", - "r-move-card-to": "Премести картицу са задатком на", + "r-when-a-attach": "Када је нека предметна грађа", + "r-when-a-checklist": "Када је нека предметна радња", + "r-when-the-checklist": "Када је предметна радња", + "r-completed": "обављена", + "r-made-incomplete": "означена као необављена", + "r-when-a-item": "Када је нека ставка са списка", + "r-when-the-item": "Када је ставка са списка", + "r-checked": "прецртана", + "r-unchecked": "означена као не прецртана", + "r-move-card-to": "Премести предмет на", "r-top-of": "Врх", "r-bottom-of": "Дно", - "r-its-list": "своје деонице", - "r-archive": "Премести у архиву", - "r-unarchive": "Извуци из архиве", - "r-card": "картица", + "r-its-list": "свог дела поступка", + "r-archive": "спакован у архиву", + "r-unarchive": "извучен из архиве", + "r-card": "предмет", "r-add": "Додај", "r-remove": "Уклони", - "r-label": "налепница", - "r-member": "сарадник", - "r-remove-all": "Удаљи све сараднике са задатка", - "r-set-color": "Обоји са", - "r-checklist": "списак за обавити", - "r-check-all": "Све је обављено", - "r-uncheck-all": "Није ништа обављено", - "r-items-check": "ставке на списку за обавити", - "r-check": "Обављено", - "r-uncheck": "Необављено", - "r-item": "ставка", - "r-of-checklist": "списка за обавити", + "r-label": "налепницу", + "r-member": "сарадника по имену", + "r-remove-all": "Скини све сареднике са предмета", + "r-set-color": "Обоји", + "r-checklist": "предметну радњу", + "r-check-all": "Прецртај све", + "r-uncheck-all": "Означи све као непрецртано", + "r-items-check": "са списка", + "r-check": "Прецртај", + "r-uncheck": "Врати на дораду", + "r-item": "ставку", + "r-of-checklist": "са списка", "r-send-email": "Пошаљи е-пошту", "r-to": "за", "r-of": "од", "r-subject": "наслов", "r-rule-details": "Детаљи извођења правила", - "r-d-move-to-top-gen": "Премести картицу са задатком на врх своје деонице", - "r-d-move-to-top-spec": "Премести картицу са задатком на врх деонице", - "r-d-move-to-bottom-gen": "Премести картицу са задатком на дно своје деонице", - "r-d-move-to-bottom-spec": "Премести картицу са задатком на дно деонице", + "r-d-move-to-top-gen": "Помери предмет на врх тог дела поступка", + "r-d-move-to-top-spec": "Помери предмет на врх дела поступка", + "r-d-move-to-bottom-gen": "Помери предмет на дно тог дела поступка", + "r-d-move-to-bottom-spec": "Помери предмет на дно дела поступка", "r-d-send-email": "Пошаљи е-пошту", "r-d-send-email-to": "за", "r-d-send-email-subject": "наслов", "r-d-send-email-message": "порука", - "r-d-archive": "Премести картицу са задатком у архиву", - "r-d-unarchive": "Извуци из архиве картицу са задатком", + "r-d-archive": "Премести предмет у архиву", + "r-d-unarchive": "Извуци предмет из архиве", "r-d-add-label": "Залепи налепницу", "r-d-remove-label": "Уклони налепницу", - "r-create-card": "Направи нову картицу са задатком", - "r-in-list": "на деоници", - "r-in-swimlane": "у стази", + "r-create-card": "Заведи предмет", + "r-in-list": "у делу", + "r-in-swimlane": "поступка", "r-d-add-member": "Прими сарадника", - "r-d-remove-member": "Удаљи сарадника", - "r-d-remove-all-member": "Удаљи све сараднике", - "r-d-check-all": "Означи све ставке на списку за обавити као обављене", - "r-d-uncheck-all": "Означи све ставке на списку за обавити као необављене", - "r-d-check-one": "Обављена ставка", - "r-d-uncheck-one": "Необављена ставка", + "r-d-remove-member": "Изузми сарадника", + "r-d-remove-all-member": "Изузми све сараднике", + "r-d-check-all": "Означи све ставке са списка као обављене", + "r-d-uncheck-all": "Означи све ставке са списка као необављене", + "r-d-check-one": "Обављена радња", + "r-d-uncheck-one": "Необављена радња", "r-d-check-of-list": "списка за обавити", - "r-d-add-checklist": "Додај списак за обавити", - "r-d-remove-checklist": "Уклони списак за обавити", + "r-d-add-checklist": "Додај списак", + "r-d-remove-checklist": "Уклони списак", "r-by": "од", - "r-add-checklist": "Додај списак за обавити", + "r-add-checklist": "Кад неко дода списак", "r-with-items": "са ставкама", "r-items-list": "ставка1,ставка2,ставка3", - "r-add-swimlane": "Додај стазу", - "r-swimlane-name": "име стазе", - "r-board-note": "Белешка: Остављено празно поље одговара свакој могућој вредности.", - "r-checklist-note": "Белешка: Ставке на списку за обавити морају да буду раздвојене зарезом.", - "r-when-a-card-is-moved": "Када је картица са задатком премештена на другу деоницу", - "r-set": "Постави", - "r-update": "Освежи", - "r-datefield": "поље са датумом", - "r-df-start-at": "почетак", - "r-df-due-at": "крајњи датум", - "r-df-end-at": "крај", - "r-df-received-at": "примљен", - "r-to-current-datetime": "до тренутног датума/времена", - "r-remove-value-from": "Уклони вредност са", - "r-link-card": "Увежи картицу на", + "r-add-swimlane": "Додај врсту поступка", + "r-swimlane-name": "врсту поступка", + "r-board-note": "Белешка: Непопуњено поље одговара свакој могућој вредности.", + "r-checklist-note": "Белешка: Ставке на списку морају да буду раздвојене зарезом.", + "r-when-a-card-is-moved": "Када је предмет премештен у други део поступка", + "r-set": "Унеси", + "r-update": "Помери", + "r-datefield": "временску одредницу кад је предмет", + "r-df-start-at": "започет", + "r-df-due-at": "орочен", + "r-df-end-at": "окончан", + "r-df-received-at": "запримљен", + "r-to-current-datetime": "на данашњи датум и тренутно време", + "r-remove-value-from": "Уклони временску одредницу из поља", + "r-link-card": "Кад је предмет у вези са списима", "ldap": "LDAP", "oauth2": "OAuth2", "cas": "CAS", @@ -898,30 +920,30 @@ "custom-product-name": "Ваша реклама", "layout": "Распоред", "hide-logo": "Сакриј лого", - "hide-card-counter-list": "Сакриј бројач задатака на картици у свим пословним књигама", - "hide-board-member-list": "Сакриј списак сарадника у свим књигама пословања", - "add-custom-html-after-body-start": "Уметни овај HTML код на сваки почетак деонице", - "add-custom-html-before-body-end": "Уметни овај HTML код пред сваки крај деонице", - "error-undefined": "Негде је настао проблем", + "hide-card-counter-list": "Сакриј бројач предмета на полици са списима", + "hide-board-member-list": "Сакриј списак сарадника на полици са списима", + "add-custom-html-after-body-start": "Уметни овај HTML код где почиње деоница", + "add-custom-html-before-body-end": "Уметни овај HTML код пред крај деонице", + "error-undefined": "Имамо непознат проблем", "error-ldap-login": "Догодила се нека грешка приликом покушаја пријављивања", "display-authentication-method": "Прикажи метод за утврђивање идентитета", "oidc-button-text": "Измени OIDC текст на дугмету", "default-authentication-method": "Уобичајени метод за утврђивање идентитета", - "duplicate-board": "Умножи пословну књигу у још један примерак", + "duplicate-board": "Умножи списе у још један примерак", "duplicate-board-confirm": "Are you sure you want to duplicate this board?", - "org-number": "Број предузећа је:", - "team-number": "Број тимова је:", - "people-number": "Број сарадника је:", - "swimlaneDeletePopup-title": "Избрисаћете стазу ?", - "swimlane-delete-pop": "Све радње ће бити уклоњене из активности и нећете моћи да вратите стазу. Нема поништавања.", + "org-number": "Број евидентираних странака је:", + "team-number": "Број правних тимова је:", + "people-number": "Укупан број сарадника је:", + "swimlaneDeletePopup-title": "Избрисаћете овај поступак ?", + "swimlane-delete-pop": "Све радње ће бити уклоњене из записника и нећете моћи да опоравите поступак. Нема поништавања.", "restore-all": "Опорави све", "delete-all": "Обриши све", "loading": "Исчитавање, молим сачекајте.", "previous_as": "прошли пут је био", - "act-a-dueAt": "измењени крајњи рок \nКада:__timeValue__\nГде:__card__\nПретходни рок је био __timeOldValue__", - "act-a-endAt": "измењено време завршетка на __timeValue__ са претходно постављеног (__timeOldValue__)", - "act-a-startAt": "измењено време почетка на __timeValue__ са претходно постављеног (__timeOldValue__)", - "act-a-receivedAt": "измењено време пријема на __timeValue__ са претходно постављеног (__timeOldValue__)", + "act-a-dueAt": "измењени крајњи рок \nРок:__timeValue__\nПредмет:__card__\nПретходни крајњи рок је био __timeOldValue__", + "act-a-endAt": "измењен датум и време окончања на __timeValue__ са претходно постављеног (__timeOldValue__)", + "act-a-startAt": "измењен датум и време почетка рада на предмету на __timeValue__ са претходно постављеног (__timeOldValue__)", + "act-a-receivedAt": "измењен датум и време пријема предмета на __timeValue__ са претходно постављеног (__timeOldValue__)", "a-dueAt": "измењен крајњи рок", "a-endAt": "измењено време завршетка", "a-startAt": "измењено време почетка", @@ -934,25 +956,25 @@ "act-almostdue": "подсећам да се приближавамо последњем року (__timeValue__) за завршетак задатка __card__", "act-pastdue": "подсећам да је последњи рок (__timeValue__) задатка __card__ пробијен", "act-duenow": "подсећам да последњи рок (__timeValue__) задатка __card__ истиче данас", - "act-atUserComment": "Споменути сте у пословној књизи [__board__] тачније на деоници __list__ на картици са задатком __card__", - "delete-user-confirm-popup": "Да ли сте сигурни да желите да избришете овај кориснички налог? Опозив ове радње неће бити могућ.", - "delete-team-confirm-popup": "Да ли сте сигурни да желите да избришете овај тим? Опозив ове радње неће бити могућ.", - "delete-org-confirm-popup": "Да ли сте сигурни да желите да избришете ово предузеће? Опозив ове радње неће бити могућ.", - "accounts-allowUserDelete": "Дозволи корисницима да сами избришу свој налог", + "act-atUserComment": "Споменути сте у списима [__board__] тачније на делу поступка __list__ у предмету __card__", + "delete-user-confirm-popup": "Да ли сте сигурни да желите да уклоните овај појединачни кориснички налог сарадника? Опозив ове радње неће бити могућ.", + "delete-team-confirm-popup": "Да ли сте сигурни да желите да уклоните овај цео правни тим? Опозив ове радње неће бити могућ.", + "delete-org-confirm-popup": "Да ли сте сигурни да желите да уклоните ову странку? Опозив ове радње неће бити могућ.", + "accounts-allowUserDelete": "Дозволи сарадницима да сами испишу свој налог из јединственог регистра", "hide-minicard-label-text": "Сакриј натпис на налепници", "show-desktop-drag-handles": "Прикажи ручке за повлачење на радној површини", - "assignee": "Извршилац", - "cardAssigneesPopup-title": "Коме се додељује да изврши", + "assignee": "Пуномоћник", + "cardAssigneesPopup-title": "Коме се даје пуномоћ", "addmore-detail": "Додај детаљнији опис", - "show-on-card": "Прикажи на картици", - "show-on-minicard": "Прикажи на налепници", + "show-on-card": "Видљиво у појединостима", + "show-on-minicard": "Видљиво на омоту", "new": "Ново", - "editOrgPopup-title": "Уреди предузеће", - "newOrgPopup-title": "Ново предузеће", - "editTeamPopup-title": "Уреди податке за тим", - "newTeamPopup-title": "Нови тим", - "editUserPopup-title": "Уреди податке корисника", - "newUserPopup-title": "Нови корисник", + "editOrgPopup-title": "Опис странке", + "newOrgPopup-title": "Нова странка", + "editTeamPopup-title": "Опис правног тима", + "newTeamPopup-title": "Нови правни тим", + "editUserPopup-title": "Опис сарадника", + "newUserPopup-title": "Нови сарадник", "notifications": "Обавештења", "help": "Помоћ", "view-all": "Прикажи сва", @@ -970,107 +992,109 @@ "saturday": "Субота", "sunday": "Недеља", "status": "Стање", - "swimlane": "Стаза", + "swimlane": "Поступак", "owner": "Власник", "last-modified-at": "Време последње измене", "last-activity": "Последње промене", "voting": "Гласање", "archived": "Архивирано", - "delete-linked-card-before-this-card": "Не можете избрисати ову картицу пре него што прво избришете повезану картицу која има", - "delete-linked-cards-before-this-list": "Не можете избрисати ову деоницу -- прво избришете повезане картице које показују на картице на овој деоници", - "hide-checked-items": "Сакриј већ обављено са списка", - "hide-finished-checklist": "Hide finished checklist", + "delete-linked-card-before-this-card": "Можете избрисати овај предмет тек кад, прво, избришете предмет у вези са њим", + "delete-linked-cards-before-this-list": "Не можете избрисати овај део поступка - прво избришете предмете који су у вези са предметима у овом делу поступка", + "hide-checked-items": "Сакриј обављене помоћне предметне радње", + "hide-finished-checklist": "Сакриј обављене предметне радње", "task": "Задатак", "create-task": "Задај", - "ok": "У реду", - "organizations": "Предузећа", - "teams": "Тимови", - "displayName": "Име које се приказује", - "shortName": "Скраћеница", - "autoAddUsersWithDomainName": "Automatically add users with the domain name", - "website": "Интернет страница", - "person": "Особа", - "my-cards": "Моја задужења", - "card": "Картица", - "list": "Деоница", - "board": "Пословна књига", + "ok": "Сагласан", + "organizations": "Странке", + "teams": "Правни тимови", + "displayName": "Име (Пословно име)", + "shortName": "Скраћено пословно име", + "autoAddUsersWithDomainName": "Повежи са оним сарадницима чији је домен е-поште", + "website": "Званична интернет страница", + "person": "Лице", + "my-cards": "Предмети где имам пуномоћ", + "card": "Предмет", + "list": "Део поступка", + "board": "Списи", "context-separator": "/", - "myCardsViewChange-title": "Приказ мојих задужења", - "myCardsViewChangePopup-title": "Приказ мојих задужења", - "myCardsViewChange-choice-boards": "Размештена по пословним књигама", - "myCardsViewChange-choice-table": "Приказана у табели", - "myCardsSortChange-title": "Издвајање мојих личних картица", - "myCardsSortChangePopup-title": "Издвајање мојих личних картица", - "myCardsSortChange-choice-board": "По натпису на књизи пословања", + "myCardsViewChange-title": "Поглед на такве предмете", + "myCardsViewChangePopup-title": "Такви предмети треба да буду", + "myCardsViewChange-choice-boards": "Размештени по списима", + "myCardsViewChange-choice-table": "Приказани у табели", + "myCardsSortChange-title": "Редослед предмета где имам пуномоћ", + "myCardsSortChangePopup-title": "Поређај предмете где имам пуномоћ", + "myCardsSortChange-choice-board": "По деловодном броју списа", "myCardsSortChange-choice-dueat": "По датуму доспећа", - "dueCards-title": "Послови којима истиче рок", - "dueCardsViewChange-title": "Приказ картица које истичу", - "dueCardsViewChangePopup-title": "Приказ картица које истичу", - "dueCardsViewChange-choice-me": "Моји недовршени послови", - "dueCardsViewChange-choice-all": "Недовршени послови сарадника", - "dueCardsViewChange-choice-all-description": "Прикажи све недовршене задатке који имају постављен рок решавања из пословних књига за које корисник има одобрење.", - "broken-cards": "Покидане картице", - "board-title-not-found": "Књига пословања '%s' није пронађена.", - "swimlane-title-not-found": "Стаза '%s' није пронађена.", - "list-title-not-found": "Деоница '%s' није пронађена.", - "label-not-found": "Налепница '%s' није пронађена.", - "label-color-not-found": "Боја налепнице %s није пронађена.", - "user-username-not-found": "Корисничко име '%s' није пронађено.", + "dueCards-title": "Предмети са роковима", + "dueCardsViewChange-title": "Надлежност", + "dueCardsViewChangePopup-title": "Надлежност", + "dueCardsViewChange-choice-me": "где имам пуномоћ", + "dueCardsViewChange-choice-all": "где имам право увида", + "dueCardsViewChange-choice-all-description": "Приказује све нерешене предмете који имају постављен рок решавања из оних списа за које корисник има одобрење.", + "dueCards-noResults-title": "Није пронађен ниједан предмет са роком", + "dueCards-noResults-description": "Тренутно немате никакве предмете који има постављене рокове.", + "broken-cards": "Предмети где је веза покидана", + "board-title-not-found": "Списи под деловодним бројем '%s' нису пронађени.", + "swimlane-title-not-found": "Ток поступка '%s' није пронађен.", + "list-title-not-found": "Део поступка '%s' није пронађен.", + "label-not-found": "Натпис на налепници '%s' није пронађен.", + "label-color-not-found": "%s налепница у боји није пронађена.", + "user-username-not-found": "Сарадник са корисничким налогом '%s' није пронађен.", "comment-not-found": "Мишљење које садржи речи '%s' није пронађено.", - "org-name-not-found": "Предузеће '%s' није пронађено.", - "team-name-not-found": "Тим '%s' није пронађен.", - "globalSearch-title": "Претрага", - "no-cards-found": "Није пронађена ни једна картица са задацима", - "one-card-found": "Пронађена је једна картица са задацима", - "n-cards-found": "Број пронађених картица са задацима: %s", - "n-n-of-n-cards-found": "__start__-__end__ од __total__ картица је нађено", - "operator-board": "пословна књига", - "operator-board-abbrev": "п", - "operator-swimlane": "стаза", - "operator-swimlane-abbrev": "с", - "operator-list": "деонице", + "org-name-not-found": "Странка по имену '%s' није пронађена.", + "team-name-not-found": "Правни тим по имену '%s' није пронађен.", + "globalSearch-title": "Претрага по списима", + "no-cards-found": "Није пронађен ни један предмет", + "one-card-found": "Пронађен је један предмет", + "n-cards-found": "Број пронађених предмета: %s", + "n-n-of-n-cards-found": "__start__-__end__ од __total__ предмета је нађено", + "operator-board": "списи", + "operator-board-abbrev": "с", + "operator-swimlane": "поступак", + "operator-swimlane-abbrev": "п", + "operator-list": "део", "operator-list-abbrev": "д", - "operator-label": "налепнице", + "operator-label": "налепницa", "operator-label-abbrev": "#", "operator-user": "корисник", "operator-user-abbrev": "@", "operator-member": "сарадник", "operator-member-abbrev": "н", - "operator-assignee": "коме је додељено", - "operator-assignee-abbrev": "о", - "operator-creator": "налогодавац", + "operator-assignee": "пуномоћник", + "operator-assignee-abbrev": "м", + "operator-creator": "завео", "operator-status": "стање", "operator-due": "крајњи датум", - "operator-created": "постављен", + "operator-created": "заведено", "operator-modified": "измењено", "operator-sort": "редослед", "operator-comment": "мишљење", "operator-has": "има", "operator-limit": "ограничење", "operator-debug": "тражење грешака", - "operator-org": "предузеће", + "operator-org": "странка", "operator-team": "тим", "predicate-archived": "архивиран", "predicate-open": "отворен", "predicate-ended": "окончан", "predicate-all": "све", "predicate-overdue": "истекао", - "predicate-week": "недеља", - "predicate-month": "месец", - "predicate-quarter": "тромесечје", - "predicate-year": "година", + "predicate-week": "недељно", + "predicate-month": "месечно", + "predicate-quarter": "тромесечно", + "predicate-year": "годишње", "predicate-due": "рок", - "predicate-modified": "измењен", - "predicate-created": "направљен", - "predicate-attachment": "прилог", - "predicate-description": "опис", - "predicate-checklist": "списак за обавити", - "predicate-start": "почетак", - "predicate-end": "крај", - "predicate-assignee": "задужени", + "predicate-modified": "изменио", + "predicate-created": "завео", + "predicate-attachment": "приложио", + "predicate-description": "описао", + "predicate-checklist": "предметна радња", + "predicate-start": "започео", + "predicate-end": "окончао", + "predicate-assignee": "овластио", "predicate-member": "сарадник", - "predicate-public": "јавно", - "predicate-private": "приватно", + "predicate-public": "јавни", + "predicate-private": "тајни", "predicate-selector": "изборник", "predicate-projection": "очекивање", "operator-unknown-error": "%s уопште није оператор", @@ -1082,76 +1106,76 @@ "operator-debug-invalid": "%s уопште није исправан предикат", "next-page": "Следећа страна", "previous-page": "Претходна страна", - "heading-notes": "Белешке", - "globalSearch-instructions-heading": "Упутство за детаљно претраживање", - "globalSearch-instructions-description": "Да би се претрага побољшала, можете да користите операторе. Оператори се задају навођењем имена оператора и навођењем вредности где се оператор и вредност раздвајају двотачком. На пример, ако задате `деоница:блокирано` то ће сузити претрагу само на оне картице са задацима које су смештене на деоници под називом *блокирано*. Уколико вредност садржи празна места или посебне знакове морате их обухватити наводницима (нпр. `__operator_list__:\"радови у току\"`).", + "heading-notes": "Додатак", + "globalSearch-instructions-heading": "Правилник за детаљно претраживање", + "globalSearch-instructions-description": "Да би сте сузили резултате претраге предлажемо Вам да почнете да користите операнде. Операнд је математички појам којег овде дефинишемо као целину која се састоји од променљиве и њене припадајуће вредности који су међусобно раздвојени двотачком. На пример, ако задате операнд `део:одложено` то ће сузити претрагу само на оне предмете који су смештени у делу поступка под називом *одложено*. Уколико вредност садржи размак између речи или садржи посебне знакове вредност морате обухватити наводницима (нпр. `__operator_list__:\"у жалбеном поступку\"`).", "globalSearch-instructions-operators": "Оператори на располагању:", - "globalSearch-instructions-operator-board": "`__operator_board__:<наслов>` - задаци на картицама у пословним књигама које садрже *<наслов>*", - "globalSearch-instructions-operator-list": "`__operator_list__:<назив>` - задаци на деоницама које садрже *<назив>*", - "globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<назив>` - задаци на стазама које садрже *<назив>*", - "globalSearch-instructions-operator-comment": "`__operator_comment__:<речи>` - задаци где је мишљење исказано *<речима>*.", - "globalSearch-instructions-operator-label": "`__operator_label__:<боја>` `__operator_label__:<име>` - задаци чија налепница има *<боју>* or *<име>", - "globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<име|боја>` - скраћеница за `__operator_label__:<боју>` или `__operator_label__:<име>`", - "globalSearch-instructions-operator-user": "`__operator_user__:<неко>` - задаци где је *<неко>* или *сарадник* или *извршилац*", + "globalSearch-instructions-operator-board": "`__operator_board__:<наслов>` - сви предмети у списима са задатим *<насловом>*", + "globalSearch-instructions-operator-list": "`__operator_list__:<назив>` - сви предмети чији део поступка има следећи *<назив>*", + "globalSearch-instructions-operator-swimlane": "`__operator_swimlane__:<врста>` - сви предмети који се налазе у задатој *<врсти>* поступка", + "globalSearch-instructions-operator-comment": "`__operator_comment__:<речи>` - сви предмети где су у расправи коришћене следеће *<речи>*.", + "globalSearch-instructions-operator-label": "`__operator_label__:<боја>` `__operator_label__:<натпис>` - сви предмети на које је залепљена налепница следеће *<боје>* а која има *<натпис>", + "globalSearch-instructions-operator-hash": "`__operator_label_abbrev__<име|боја>` - скраћеница за `__operator_label__:<боја>` или `__operator_label__:<име>`", + "globalSearch-instructions-operator-user": "`__operator_user__:<неко>` - сви предмети где је *<неко>* или *сарадник* или *пуномоћник*", "globalSearch-instructions-operator-at": "`__operator_user_abbrev__корисничко име` - скраћеница за `user:<корисничко име>`", - "globalSearch-instructions-operator-member": "`__operator_member__:<неко>` - задаци где је *<неко>* *сарадник*", - "globalSearch-instructions-operator-assignee": "`__operator_assignee__:<неко>` - задаци где је *<неком>* *додељен* задатак", - "globalSearch-instructions-operator-creator": "`__operator_creator__:<неко>` - задаци где је *<неко>* направио картицу са задатком", - "globalSearch-instructions-operator-org": "`__operator_org__:<назив предузећа|скраћени назив>` - задаци који припадају пословној књизи додељеној *<предузећу>*", - "globalSearch-instructions-operator-team": "`__operator_team__:<назив тима|скраћени назив>` - задаци који припадају пословној књизи додељеној *<тиму>*", - "globalSearch-instructions-operator-due": "`__operator_due__:` - задаци чији рок истиче за ** дана. `__operator_due__:__predicate_overdue__ приказује списак свих задатака са истеклим роком.", - "globalSearch-instructions-operator-created": "`__operator_created__:` - задаци који су постављени пре ** или мање дана", - "globalSearch-instructions-operator-modified": "`__operator_modified__:` - задаци који су измењени пре ** или мање дана", + "globalSearch-instructions-operator-member": "`__operator_member__:<неко>` - предмети где је *<неко>* сарадник", + "globalSearch-instructions-operator-assignee": "`__operator_assignee__:<неко>` - предмети где је *<неко>* пуномоћник", + "globalSearch-instructions-operator-creator": "`__operator_creator__:<неко>` - предмети које је завео *<неко>*", + "globalSearch-instructions-operator-org": "`__operator_org__:<име или пословно име|скраћено пословно име>` - предмети у вези са *<странком>*", + "globalSearch-instructions-operator-team": "`__operator_team__:<назив тима|скраћени назив>` - предмети које обрађује правни тим *<назив>*", + "globalSearch-instructions-operator-due": "`__operator_due__:` - предмети чији рок истиче за ** дана. `__operator_due__:__predicate_overdue__ предмети са истеклим роком.", + "globalSearch-instructions-operator-created": "`__operator_created__:` - предмети који су заведени у задњих ** дана", + "globalSearch-instructions-operator-modified": "`__operator_modified__:` - предмети који су имали измене у задњих ** дана", "globalSearch-instructions-operator-status": "`__operator_status__:<стање>` - где се под *<стањем>* подразумева једно од следећих:", - "globalSearch-instructions-status-archived": "`__predicate_archived__` - архивирани задаци", + "globalSearch-instructions-status-archived": "`__predicate_archived__` - архивирани предмети", "globalSearch-instructions-status-all": "`__predicate_all__` - сви архивирани и неархивирани задаци", - "globalSearch-instructions-status-ended": "`__predicate_ended__` - задаци где је постављен датум завршетка", - "globalSearch-instructions-status-public": "`__predicate_public__` - једино задаци у јавним пословним књигама", - "globalSearch-instructions-status-private": "`__predicate_private__` - једино задаци у приватним пословним књигама", - "globalSearch-instructions-operator-has": "`__operator_has__:<поље>` - где је то *<поље>* једно од `__predicate_attachment__`, `__predicate_checklist__`, `__predicate_description__`, `__predicate_start__`, `__predicate_due__`, `__predicate_end__`, `__predicate_assignee__` или `__predicate_member__`. Уколико уметнете знак минус `-` испред тог *<поља>* претражује се недостатак те вредности (нпр `има:-рок` претражује задатке без постављеног рока).", + "globalSearch-instructions-status-ended": "`__predicate_ended__` - сви окончани предмети", + "globalSearch-instructions-status-public": "`__predicate_public__` - предмети видљиви свима на интернету", + "globalSearch-instructions-status-private": "`__predicate_private__` - предмети видљиви искључиво сарадницима", + "globalSearch-instructions-operator-has": "`__operator_has__:<поље>` - где је то *<поље>* једно од `__predicate_attachment__`, `__predicate_checklist__`, `__predicate_description__`, `__predicate_start__`, `__predicate_due__`, `__predicate_end__`, `__predicate_assignee__` или `__predicate_member__`. Уколико уметнете знак минус `-` испред тог *<поља>* претражује се недостатак те вредности (нпр `има:-рок` претражује предмете без постављеног рока).", "globalSearch-instructions-operator-sort": "`__operator_sort__:<правило>` - где је *<правило>* једно од `__predicate_due__`, `__predicate_created__` или `__predicate_modified__`. За опадајући редослед уметните минус `-` испред правила.", - "globalSearch-instructions-operator-limit": "`__operator_limit__:` - позитиван цео број ** представља број задатака који се приказују по страни.", + "globalSearch-instructions-operator-limit": "`__operator_limit__:` - позитиван цео број ** представља број предмета који се приказују по страни.", "globalSearch-instructions-notes-1": "Можете истовремено задати више оператора.", - "globalSearch-instructions-notes-2": "Над поновљеним операторима се изводи операција логичко ИЛИ. Биће приказани задаци који испуњавају било који од услова.\n`__operator_list__:Доступно __operator_list__:Блокирано` као резултат приказује све картице које су било у деоници *Блокирано* било у деоници *Доступно*.", - "globalSearch-instructions-notes-3": "На различитим операторима се изводи операција логичко И. Биће приказани само они задаци који испуњавају све услове. `__operator_list__:Доступно __operator_label__:црвено` приказаће међу свим задацима на деоници *Доступно* само оне са *црвеном* налепницом.", + "globalSearch-instructions-notes-2": "Над сродним операторима се изводи операција логичко ИЛИ. Биће приказани предмети који испуњавају било који од услова.\n`__operator_list__:Припрема __operator_list__:Жалба` као резултат приказује све предмете које су било у деоници *Припрема* било у деоници *Жалба*.", + "globalSearch-instructions-notes-3": "На несродним операторима се изводи операција логичко И. Биће приказани само они задаци који испуњавају све услове. `__operator_list__:Жалба __operator_label__:црвена` приказаће међу свим предметима у *жалбеном* делу поступка само оне са *црвеном* налепницом.", "globalSearch-instructions-notes-3-2": "Дани се могу задати као позитивни или негативни цели бројеви или се користе `__predicate_week__`, `__predicate_month__`, `__predicate_quarter__` or `__predicate_year__` за текући период.", - "globalSearch-instructions-notes-4": "Претрага речи не прави разлику између малих и великих слова.", - "globalSearch-instructions-notes-5": "Преподешено је да се архивиране картице са задацима не претражују.", + "globalSearch-instructions-notes-4": "Разлика између малих и великих слова се не узима у обзир.", + "globalSearch-instructions-notes-5": "Ако нисте ништа дирали, претрагом неће бити обухваћени предмети из архиве.", "link-to-search": "Повежи до ове претраге", "excel-font": "Arial словни лик", "number": "Број", - "label-colors": "Боје налепница", + "label-colors": "Налепнице у боји", "label-names": "Натписи на налепницама", - "archived-at": "време архивирања", - "sort-cards": "Пресложи картице", - "sort-is-on": "Слагање је укључено", - "cardsSortPopup-title": "Пресложи картице", - "due-date": "Датум истека", + "archived-at": "датум и време архивирања", + "sort-cards": "Сложи предмете", + "sort-is-on": "Предмети су сложени", + "cardsSortPopup-title": "Сложи предмете", + "due-date": "По крајњем року", "server-error": "Грешка на серверу", "server-error-troubleshooting": "Молим да нам пошаљете извештај о грешци коју је изазвао сервер.\nАко је у питању snap инсталација, покрените: `sudo snap logs wekan.wekan`\nАко је у питању Docker инсталација, покрените: `sudo docker logs wekan-app`", - "title-alphabetically": "Наслов (Азбучним редом)", - "created-at-newest-first": "Кад је направљено (Најновије прво)", - "created-at-oldest-first": "Кад је направљено (Најстарије прво)", + "title-alphabetically": "По наслову абучним редом", + "created-at-newest-first": "По најновијим запримљеним", + "created-at-oldest-first": "По најстарије запримљеним)", "links-heading": "Везе", "hide-activities-of-all-boards": "Don't show the board activities on all boards", "now-activities-of-all-boards-are-hidden": "Now all activities of all boards are hidden", - "move-swimlane": "Премести стазу", - "moveSwimlanePopup-title": "Премештање стазе", - "custom-field-stringtemplate": "Предложак за словни низ", + "move-swimlane": "Премести ток поступка", + "moveSwimlanePopup-title": "Премештање тока поступка", + "custom-field-stringtemplate": "Образац за словни низ", "custom-field-stringtemplate-format": "Облик (користите %{вредност} као основу/носач)", "custom-field-stringtemplate-separator": "Раздвајач (користите или   за размак)", "custom-field-stringtemplate-item-placeholder": "Притисните ентер да додате још ставки", - "creator": "Задао", - "creator-on-minicard": "Creator on minicard", - "filesReportTitle": "Извештај везан за датотеке", + "creator": "Завео", + "creator-on-minicard": "Завео", + "filesReportTitle": "Извештај везан за предметну грађу", "reports": "Извештаји", "rulesReportTitle": "Извештај везан за правила", - "boardsReportTitle": "Извештај везан за пословне књиге", - "cardsReportTitle": "Извештај везан за картице", - "copy-swimlane": "Умножи стазу", - "copySwimlanePopup-title": "Умножавање стазе", - "display-card-creator": "Прикажи ко је направио картицу", - "wait-spinner": "Док се исчитава пословна књига", + "boardsReportTitle": "Извештај везан за списе", + "cardsReportTitle": "Извештај везан за предмете", + "copy-swimlane": "Умножи ток поступка", + "copySwimlanePopup-title": "Умножавање тока поступка", + "display-card-creator": "Прикажи ко је завео предмет", + "wait-spinner": "Док се исчитавају списи", "Bounce": "Исцртавај три тачкице", "Cube": "Исцртавај квадратиће", "Cube-Grid": "Исцртавај мрежу квадратића", @@ -1160,16 +1184,16 @@ "Rotateplane": "Исцртавај лист који се окреће", "Scaleout": "Исцртавај удаљавање", "Wave": "Исцртавај таласе", - "maximize-card": "Увећај картицу", - "minimize-card": "Умањи картицу", - "delete-org-warning-message": "Не могу да угасим ово предузеће пошто постоји барем један корисник који му припада", - "delete-team-warning-message": "Не могу да расформирам овај тим пошто постоји барем један корисник који му припада", + "maximize-card": "Рашири предметне списе", + "minimize-card": "Састави предметне списе", + "delete-org-warning-message": "Не могу да избацим ову странку пошто постоји барем један везани сарадник", + "delete-team-warning-message": "Не могу да распустим овај правни тим пошто постоји барем једно лице које му припада", "subject": "Тема", "details": "Детаљи", "carbon-copy": "још један примерак", - "ticket": "Предмет", - "tickets": "Предмети", - "ticket-number": "Број предмета", + "ticket": "Пријава квара", + "tickets": "Пријављени кварови", + "ticket-number": "Пријавни број", "open": "Отворен", "pending": "На чекању", "closed": "Затворен", @@ -1179,14 +1203,14 @@ "request": "Захтев", "requests": "Захтеви", "help-request": "Захтева се помоћ", - "editCardSortOrderPopup-title": "Промените правило слагања картица", - "cardDetailsPopup-title": "Појединости картице", + "editCardSortOrderPopup-title": "Промените редослед слагања предмета", + "cardDetailsPopup-title": "Шире радње на предмету", "add-teams": "Додај тимове", "add-teams-label": "Додати тимови су приказани доле:", - "remove-team-from-table": "Да ли сте сигурни да желите да уклоните овај тим из пословне књиге ?", + "remove-team-from-table": "Да ли сте сигурни да желите да овом правном тиму укинете увид у ове списе ?", "confirm-btn": "Потврди", "remove-btn": "Уклони", - "filter-card-title-label": "Издвој по наслову картице са задатком", + "filter-card-title-label": "Издвој по наслову предмета", "invite-people-success": "Позив за сарадњу је успешно послат", "invite-people-error": "Догодила се грешка приликом слања позива за сарадњу", "can-invite-if-same-mailDomainName": "Домен за електронску пошту", @@ -1206,112 +1230,350 @@ "Node_memory_usage_heap_total": "Node искоришћење меморије: укупан простор који је алоциран за heap", "Node_memory_usage_heap_used": "Node искоришћење меморије: колико заправо је искоришћено", "Node_memory_usage_external": "Node искоришћење меморије: спољна", - "add-organizations": "Додај предузећа", - "add-organizations-label": "Додана предузећа су приказана доле:", - "remove-organization-from-board": "Да ли сте сигурни да желите да уклоните ово предузеће из ове пословне књиге ?", - "to-create-organizations-contact-admin": "Да би могли да додајете предузећа, молим да се обратите управнику/администратору.", + "add-organizations": "Додај странке", + "add-organizations-label": "Странке које имају увид су приказана доле:", + "remove-organization-from-board": "Да ли сте сигурни да желите да овој странци забраните увид у ове списе ?", + "to-create-organizations-contact-admin": "Да би могли да додајете странке, молим да се обратите управнику/администратору.", "custom-legal-notice-link-url": "Место на Интернету са условима/уговором за коришћење", "acceptance_of_our_legalNotice": "Ако наставите даље, сагласни сте да прихватате наше", "legalNotice": "услови коришћења", "copied": "Умножено!", - "checklistActionsPopup-title": "Радње на списковима за обавити", - "moveChecklist": "Премести списак за обавити", - "moveChecklistPopup-title": "Премести списак за обавити", - "newlineBecomesNewChecklistItem": "Each line of text becomes one of the checklist items", - "newLineNewItem": "One line of text = one checklist item", - "newlineBecomesNewChecklistItemOriginOrder": "Each line of text becomes one of the checklist items, original order", - "originOrder": "original order", + "checklistActionsPopup-title": "Руковање списковима радњи", + "moveChecklist": "Премести списак радњи", + "moveChecklistPopup-title": "Премести списак радњи", + "newlineBecomesNewChecklistItem": "Сваки ред текста постаје ставка на списку", + "newLineNewItem": "Један ред = једна ставка", + "newlineBecomesNewChecklistItemOriginOrder": "Сваки ред текста постаје ставка на списку - по изворном редоследу уноса", + "originOrder": "изворни редослед", "copyChecklist": "Умножи списак", "copyChecklistPopup-title": "Умножи списак", - "card-show-lists": "Прикажи спискове на картици", - "subtaskActionsPopup-title": "Радње на под задацима", + "card-show-lists": "Прикажи делове поступка на омоту предмета", + "subtaskActionsPopup-title": "Радње на издвојеним пословима", "attachmentActionsPopup-title": "Однос према прилозима", "attachment-move-storage-fs": "Премести прилог у локални систем датотека", "attachment-move-storage-gridfs": "Премести прилог у GridFS", - "attachment-move-storage-s3": "Премести прилог у облак на S3", + "attachment-move-storage-s3": "Премести прилог у облак на Amazon S3", "attachment-move": "Премести прилог", - "move-all-attachments-to-fs": "Премести све прилоге у локални систем датотека", - "move-all-attachments-to-gridfs": "Премести све прилоге у GridFS", - "move-all-attachments-to-s3": "Премести све прилоге у облак на S3", - "move-all-attachments-of-board-to-fs": "Премести све прилоге пословне књиге у локални систем датотека", - "move-all-attachments-of-board-to-gridfs": "Премести све прилоге пословне књиге у GridFS", - "move-all-attachments-of-board-to-s3": "Премести све прилоге пословне књиге у облак на S3", + "move-all-attachments-to-fs": "Премести целокупну предметну грађу у локални систем датотека", + "move-all-attachments-to-gridfs": "Премести целокупну предметну грађу у MongoDB GridFS", + "move-all-attachments-to-s3": "Премести целокупну предметну грађу из списа у облак на Amazon S3", + "move-all-attachments-of-board-to-fs": "Премести предметну грађу ових списа у локални систем датотека", + "move-all-attachments-of-board-to-gridfs": "Премести предметну грађу ових списа у MongoDB GridFS", + "move-all-attachments-of-board-to-s3": "Премести предметну грађу ових списа у облак на Amazon S3", "path": "Путања", "version-name": "Назив издања", "size": "Величина", "storage": "Складиште", "action": "Радња", - "board-title": "Натпис на пословној књизи", + "board-title": "Деловодни број", "attachmentRenamePopup-title": "Преименуј", "uploading": "Подижем на сервер", "remaining_time": "Преостало време", "speed": "Брзина", "progress": "Напредак", - "password-again": "Лозинка (понови је)", - "if-you-already-have-an-account": "Ако већ имате један налог", - "register": "Регистрација", + "password-again": "Поновљена лозинка", + "if-you-already-have-an-account": "Ако већ поседујете налог ⇨ ", + "register": "Упиши се", "forgot-password": "Заборављена лозинка", - "minicardDetailsActionsPopup-title": "Појединости картице", + "minicardDetailsActionsPopup-title": "Предмет у омоту", "Mongo_sessions_count": "Број Mongo сесија", - "change-visibility": "Промени видљивост", + "change-visibility": "Промени тајност списа", "max-upload-filesize": "Максимална величина датотеке за слање (у бајтима):", "allowed-upload-filetypes": "Дозвољене врсте датотека за слање:", - "max-avatar-filesize": "Максимална величина сличице (у бајтима):", + "max-avatar-filesize": "Максимална величина слике (у бајтима):", "allowed-avatar-filetypes": "Дозвољене врсте слика:", - "invalid-file": "Ако са именом датотеке нешто није у реду тада ће и слање и преименовање бити отказано.", - "preview-pdf-not-supported": "Ваш уређај не подржава приказивање ПДФ докумената. Пробајте да преузмете документ.", - "drag-board": "Пренеси пословну књигу", - "translation-number": "Број прилагођених превода је:", - "delete-translation-confirm-popup": "Да ли сте сигурни да желите да избришете овај прилагођени превод? Опозив ове радње неће бити могућ.", - "newTranslationPopup-title": "Нови прилагођени превод", - "editTranslationPopup-title": "Уреди прилагођени превод", - "settingsTranslationPopup-title": "Обриши овај прилагођени превод", - "translation": "Превод", - "text": "Текст", - "translation-text": "Превод текста", - "show-subtasks-field": "Прикажи поље за подзадатке", + "invalid-file": "Ако са именом нешто није у реду тада ће и слање и преименовање бити отказано.", + "preview-pdf-not-supported": "Ваш уређај не подржава приказивање pdf докумената. Пробајте да преузмете документ.", + "drag-board": "Пребаци списе", + "translation-number": "Број исправки превода је:", + "delete-translation-confirm-popup": "Да ли сте сигурни да желите да избришете ову исправку превода? Опозив ове радње неће бити могућ.", + "newTranslationPopup-title": "Нова исправка превода", + "editTranslationPopup-title": "Исправи превод", + "settingsTranslationPopup-title": "Обриши ову исправку превода", + "translation": "Речник", + "text": "Изворна реченица", + "translation-text": "Превод", + "show-subtasks-field": "Прикажи поље издвојени послови", "show-week-of-year": "Show week of year (ISO 8601)", - "convert-to-markdown": "Претвори у маркдаун", - "import-board-zip": "Add .zip file that has board JSON files, and board name subdirectories with attachments", - "collapse": "Сажми", - "uncollapse": "Uncollapse", - "hideCheckedChecklistItems": "Hide checked checklist items", - "hideAllChecklistItems": "Hide all checklist items", - "support": "Support", - "supportPopup-title": "Support", - "accessibility": "Accessibility", - "accessibility-page-enabled": "Accessibility page enabled", - "accessibility-info-not-added-yet": "Accessibility info has not been added yet", - "accessibility-title": "Accessibility title", - "accessibility-content": "Accessibility content", - "accounts-lockout-settings": "Brute Force Protection Settings", - "accounts-lockout-info": "These settings control how login attempts are protected against brute force attacks.", - "accounts-lockout-known-users": "Settings for known users (correct username, wrong password)", - "accounts-lockout-unknown-users": "Settings for unknown users (non-existent username)", - "accounts-lockout-failures-before": "Failures before lockout", - "accounts-lockout-period": "Lockout period (seconds)", - "accounts-lockout-failure-window": "Failure window (seconds)", - "accounts-lockout-settings-updated": "Brute force protection settings have been updated", - "accounts-lockout-locked-users": "Locked Users", - "accounts-lockout-locked-users-info": "Users currently locked out due to too many failed login attempts", - "accounts-lockout-no-locked-users": "There are currently no locked users", - "accounts-lockout-failed-attempts": "Failed Attempts", - "accounts-lockout-remaining-time": "Remaining Time", - "accounts-lockout-user-unlocked": "User has been unlocked successfully", - "accounts-lockout-confirm-unlock": "Are you sure you want to unlock this user?", - "accounts-lockout-confirm-unlock-all": "Are you sure you want to unlock all locked users?", - "accounts-lockout-show-locked-users": "Show locked users only", - "accounts-lockout-user-locked": "User is locked", - "accounts-lockout-click-to-unlock": "Click to unlock this user", - "accounts-lockout-status": "Стање", - "admin-people-filter-show": "Show:", - "admin-people-filter-all": "Недовршени послови сарадника", - "admin-people-filter-locked": "Locked Users Only", - "admin-people-filter-active": "На окупу", - "admin-people-filter-inactive": "Not Active", - "admin-people-active-status": "Active Status", - "admin-people-user-active": "User is active - click to deactivate", - "admin-people-user-inactive": "User is inactive - click to activate", - "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "convert-to-markdown": "Претвори у структуирани текст", + "import-board-zip": "Додај .zip архиву која има списе у json облику и фасцикле по имену списа где је предметна грађа", + "collapse": "Скупи", + "uncollapse": "Рашири", + "hideCheckedChecklistItems": "Сакриј све обављене помоћне предметне радње", + "hideAllChecklistItems": "Сакриј све помоћне предметне радње", + "support": "Подршка", + "supportPopup-title": "Подршка", + "accessibility": "Особе са посебним потешкоћама", + "accessibility-page-enabled": "Омогући страницу за особе са посебним потешкоћама", + "accessibility-info-not-added-yet": "Информације намењене особама са посебним потешкоћама, за сада, нису додате", + "accessibility-title": "Наслов такве странице", + "accessibility-content": "Садржај такве странице", + "accounts-lockout-settings": "Заштитне мере од насилног упада", + "accounts-lockout-info": "Овим мерама се штитимо од насилних покушаја пријављивања погађањем лозинкеf.", + "accounts-lockout-known-users": "Мере за познате налоге (где налог постоји али се лозинка не подудара)", + "accounts-lockout-unknown-users": "Мере за непознате налоге (где сарадник са таквим корисничким именом не постоји)", + "accounts-lockout-failures-before": "Граница неуспешних покушаја пријаве (након које се сараднику одузима право приступа)", + "accounts-lockout-period": "Трајање мере забране (у секундама)", + "accounts-lockout-failure-window": "Временски оквир у којем се одиграва насилан упад (у секундама)", + "accounts-lockout-settings-updated": "Мере против насилног упада су допуњене", + "accounts-lockout-locked-users": "Налози на мерама", + "accounts-lockout-locked-users-info": "Сарадници којима је одузето право приступа због превеликог броја неуспешних покушаја пријаве", + "accounts-lockout-no-locked-users": "Тренутно не постоје налози са мером забране права приступа", + "accounts-lockout-failed-attempts": "Број неуспешних покушаја", + "accounts-lockout-remaining-time": "Преостало време", + "accounts-lockout-user-unlocked": "Налог је успешно скинут са мера забране приступа", + "accounts-lockout-confirm-unlock": "Да ли сте сигурни да желите да скинете овај налог са мера?", + "accounts-lockout-confirm-unlock-all": "Да ли сте сигурни да желите да скинете све налоге са мера?", + "accounts-lockout-show-locked-users": "Прикажи само налоге на мерама", + "accounts-lockout-user-locked": "Налог је на мерама", + "accounts-lockout-click-to-unlock": "Притисните да налог добије право приступа", + "accounts-lockout-status": "Право приступа", + "admin-people-filter-show": "Издвој:", + "admin-people-filter-all": "Обухвати све расположиве сараднике", + "admin-people-filter-locked": "Налоге на мерама забране права приступа", + "admin-people-filter-active": "Сарадник је на платном списку", + "admin-people-filter-inactive": "Сарадник више није на платном списку", + "admin-people-active-status": "Радни однос", + "admin-people-user-active": "Сарадник је на платном списку - притисните да би прекинули сарадњу", + "admin-people-user-inactive": "Сарадник није на платном списку - притисните да би га увели на платни списак", + "accounts-lockout-all-users-unlocked": "Сви сарадници којима је претходно било одузето право пријаве су скинути са ове мере", + "accounts-lockout-unlock-all": "Скини све са мера", + "active-cron-jobs": "Већ унапред заказани послови:", + "add-cron-job": "Закажи нови посао", + "add-cron-job-placeholder": "Ова функционалност биће ускоро додата", + "attachment-storage-configuration": "Поставка складишта предметне грађе", + "attachments-path": "Пуна путања до складишта", + "attachments-path-description": "Путања до складишта где се чува предметна грађа", + "avatars-path": "Путања до слика сарадника", + "avatars-path-description": "Путања где се складиште слике сарадника", + "board-archive-failed": "Није успело заказивање архивирања списа", + "board-archive-scheduled": "Заказано је паковање списа у архиву", + "board-backup-failed": "Није успело заказивање израде резервног примерка списа", + "board-backup-scheduled": "Заказана је израда резервног примерка списа", + "board-cleanup-failed": "Није успело заказивање чишћења списа", + "board-cleanup-scheduled": "Заказано је чишћење списа", + "board-operations": "Радње на списима", + "cron-jobs": "Заказани послови", + "cron-migrations": "Заказани поступци обнове оштећених списа", + "cron-job-delete-confirm": "Да ли сте сигурни да желите да уклоните заказано?", + "cron-job-delete-failed": "Није успело уклањање заказаног посла", + "cron-job-deleted": "Успешно је уклоњен заказани посао", + "cron-job-pause-failed": "Није успело паузирање заказаног посла", + "cron-job-paused": "Заказани посао је успешно паузиран", + "filesystem-path-description": "Почетак пута до складишта предметне грађе", + "gridfs-enabled": "GridFS ради и можете га користити", + "gridfs-enabled-description": "Можете користити MongoDB GridFS за складиште предметне грађе", + "migration-pause-failed": "Није било могуће направити предах у поступку обнове оштећених списа", + "migration-paused": "Направљен је предах у поступку обнове оштећених списа", + "migration-progress": "Напредак у току обнове", + "migration-start-failed": "Није било могуће покренути обнову оштећених списа", + "migration-started": "Обнова оштећених списа је започета", + "migration-status": "Пресек стања", + "migration-stop-confirm": "Да ли сте сигурни да желите да зауставите све поступке обнове оштећених предметних списа?", + "migration-stop-failed": "Није било могуће прекинути поступке обнове оштећених списа", + "migration-stopped": "Поступци обнове оштећених списа су управо заустављени", + "mongodb-gridfs-storage": "MongoDB GridFS складиште", + "pause-all-migrations": "Предах за све", + "s3-access-key": "S3 приступни кључ", + "s3-access-key-description": "AWS S3 приступни кључ за пријаву", + "s3-access-key-placeholder": "Унесите S3 приступни кључ", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket име где чувате предметну грађу", + "s3-connection-failed": "S3 веза је у прекиду", + "s3-connection-success": "Управо је остварена веза до S3", + "s3-enabled": "S3 ради и може да се користи", + "s3-enabled-description": "Можете да користите AWS S3 или MinIO као складиште предметне грађе", + "s3-endpoint": "S3 Endpoint тачка", + "s3-endpoint-description": "S3 endpoint тачка (нпр. s3.amazonaws.com или minio.example.com)", + "s3-minio-storage": "S3/MinIO складиште", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port број", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 регион (нпр. us-east-1)", + "s3-secret-key": "S3 тајни кључ", + "s3-secret-key-description": "AWS S3 тајни кључ за пријаву", + "s3-secret-key-placeholder": "Унесите S3 тајни кључ", + "s3-secret-key-required": "Тражи се и S3 тајни кључ", + "s3-settings-save-failed": "Није могла бити сачувана S3 поставка", + "s3-settings-saved": "S3 поставка је сачувана", + "s3-ssl-enabled": "S3 SSL шифровање је укључено", + "s3-ssl-enabled-description": "Користи SSL/TLS за везу до Amazon S3 складишта", + "save-s3-settings": "Сачувај ову S3 поставку", + "schedule-board-archive": "Закажи архивирање списа", + "schedule-board-backup": "Закажи израду резервног примерка", + "schedule-board-cleanup": "Закажи чишћење", + "scheduled-board-operations": "Заказане радње на списима", + "start-all-migrations": "Пуна обнова", + "stop-all-migrations": "Прекини поступке", + "test-s3-connection": "Проба везе до Amazon S3", + "writable-path": "Проходна путања", + "writable-path-description": "Почетак путање према складишту предметне грађе", + "add-job": "Додај посао", + "attachment-migration": "Пресељење предметне грађе", + "attachment-monitoring": "Надзор над предметном грађом", + "attachment-settings": "Рад са предметном грађом", + "attachment-storage-settings": "Складиште предметне грађе", + "automatic-migration": "Обнављај иза у тишини", + "back-to-settings": "Натраг на поставку", + "board-id": "BoardID", + "board-migration": "Обнова оштећених списа", + "board-migrations": "Поступци обнове оштећених списа", + "card-show-lists-on-minicard": "Прикажи део поступка на омоту", + "comprehensive-board-migration": "Свеобухватна обнова", + "comprehensive-board-migration-description": "Изводе се свеобухватне провера и врше поправке целовитости података у списима - што укључује провере и поправке редоследа делова поступака, места где се тачно предмети налазе и структуре поступака.", + "delete-duplicate-empty-lists-migration": "Брисање истоимених делова поступка", + "delete-duplicate-empty-lists-migration-description": "На један безбедан начин брише празне истоимене делове поступка. Бришу се сви делови поступка у којима нема предмета ако постоји део поступка са истим тим насловом где већ постоје предмети.", + "lost-cards": "Загубљени предмети", + "lost-cards-list": "Опорављени предмети", + "restore-lost-cards-migration": "Опоравак загубљених предмета", + "restore-lost-cards-migration-description": "Открива и опоравља предмете и делове поступака којима недостају поља swimlaneId или listId и смешта у „Опорављене предмете“.", + "restore-all-archived-migration": "Опоравак свих предмета из архиве", + "restore-all-archived-migration-description": "Опоравља све архивиране делове поступака, поступке и предмете притом поправљајући недостајућа поља swimlaneId или listId.", + "fix-missing-lists-migration": "Поправка кад недостају делови поступка", + "fix-missing-lists-migration-description": "Открива и поправља сваки део поступка који недостаје или који је оштећен.", + "fix-avatar-urls-migration": "Поправка кад се не виде слике сарадника", + "fix-avatar-urls-migration-description": "Исправља везу до складишта са сликама сарадника из ових списа.", + "fix-all-file-urls-migration": "Поправка кад ишчезне предметна грађа", + "fix-all-file-urls-migration-description": "Преусмерава везу ка складишту где се стварно налази предметна грађа из ових списа.", + "migration-needed": "Потребна је обнова", + "migration-complete": "Обнова је обављена", + "migration-running": "Обнова је у току...", + "migration-successful": "Обнова је успешно окончана", + "migration-failed": "Обнова није била успешна", + "migrations": "Радионица", + "migrations-admin-only": "За обнову ових списа надлежан је једино онај ко је њихов управник", + "migrations-description": "Овде може да се изврши провера целовитости података и поправка оштећења. Сваки поступак обнове се може спровести независно један од другог", + "no-issues-found": "Нису уочена оштећења", + "run-migration": "Покрени опоравак", + "run-comprehensive-migration-confirm": "Овим ће бити изведене свеобухватне провере и поправке целовитости података у списима. То би кратко трајало уколико сте сагласни?", + "run-delete-duplicate-empty-lists-migration-confirm": "Овим ће прво сви дељени делови поступака бити везани на саме поступке, затим ће бити избрисан сваки део поступка који је празан где постоји део поступка истог имена који има предмете. Да ли сте сагласни?", + "run-restore-lost-cards-migration-confirm": "Овим се прави ток „Загубљени предмети“ и у њега смештају сви предмети и делови поступка којима недостају поља swimlaneId или listId. Мисли се на оно што је загубљено али није загубљено у архиви. Да ли сте сагласни? ", + "run-restore-all-archived-migration-confirm": "Овим се износи натраг из архиве све оно што сте до сада спаковали тамо. Поља где недостаје id биће поправљена. Упозорење! Да ли заиста то желите?", + "run-fix-missing-lists-migration-confirm": "Овим се откривају и поправљају они делови поступака који недостају или који су оштећени. Да ли сте сагласни?", + "run-fix-avatar-urls-migration-confirm": "Овим се исправља веза до складишта са сликама сарадника из ових списа. Да ли сте сагласни?", + "run-fix-all-file-urls-migration-confirm": "Овим ће бити исправљене све везе у списима да упућују на стварно складиште предметне грађе. Да ли сте сагласни?", + "restore-lost-cards-nothing-to-restore": "Нема нити загубљених поступака нити предмета за опоравак", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Укупни напредак", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Стање", + "migration-progress-details": "Појединости", + "migration-progress-note": "Молимо да будете стрпљиви док траје препакивање Ваших списа...", + + "step-analyze-board-structure": "Изучавам везе у списима", + "step-fix-orphaned-cards": "Поправљам одбачене предмете", + "step-convert-shared-lists": "Претварам дељене делове поступка", + "step-ensure-per-swimlane-lists": "Осигуравам да је део поступка везан за поступак", + "step-validate-migration": "Оцењујем обнову", + "step-fix-avatar-urls": "Поправљам везе до складишта слика за сараднике", + "step-fix-attachment-urls": "Поправљам везе до складишта предметне грађе", + "step-analyze-lists": "Изучавам делове поступка", + "step-create-missing-lists": "Стварам недостајуће делове", + "step-update-cards": "Допуњујем предмете", + "step-finalize": "Завршавам", + "step-delete-duplicate-empty-lists": "Бришем исте празне делове поступка", + "step-ensure-lost-cards-swimlane": "Правим место за загубљене предмете", + "step-restore-lists": "Опорављам делове поступка", + "step-restore-cards": "Опорављам предмете", + "step-restore-swimlanes": "Опорављам читав ток поступка", + "step-fix-missing-ids": "Поправљам недостајућа id поља", + "step-scan-users": "Проверавам слике сарадника на списима", + "step-scan-files": "Проверавам предметну грађу", + "step-fix-file-urls": "Поправљам везе до предметне грађе", + "cleanup": "Чистим", + "cleanup-old-jobs": "Чистим остављено", + "completed": "Прошао сам кроз све кораке", + "conversion-info-text": "Ово преслагање се изводи само једном по спису и то после олакшава читање. Без сметњи настављате да читате спис након тога.", + "converting-board": "Преслагање списа", + "converting-board-description": "Преслагање списа олакшава употребу. Ово може потрајати неколико тренутака.", + "cpu-cores": "Процесорска језгра", + "cpu-usage": "Заузеће процесора", + "current-action": "Текућа радња", + "database-migration": "Обнова базе података", + "database-migration-description": "Преслажем структуру базе података да би била боља и бржа. Процес може потрајати неколико минута.", + "database-migrations": "Преслагање базе података", + "days-old": "дана стар", + "duration": "Трајање", + "errors": "Грешке", + "estimated-time-remaining": "Процењено преостало време", + "every-1-day": "Једном дневно", + "every-1-hour": "На сваки сат", + "every-1-minute": "На сваки минут", + "every-10-minutes": "На сваких десет минута", + "every-30-minutes": "На сваких пола сата", + "every-5-minutes": "На пет минута", + "every-6-hours": "На шест сати", + "export-monitoring": "Надзор током изношења", + "filesystem-attachments": "Локална предметна грађа", + "filesystem-size": "Величина локалног складишта", + "filesystem-storage": "Локално складиште", + "force-board-scan": "Читање списа на силу", + "gridfs-attachments": "GridFS раздељена предметна грађа", + "gridfs-size": "GridFS величина", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Сакриј део поступка са омота", + "idle-migration": "Тиха обнова", + "job-description": "Опис посла", + "job-details": "Појединости посла", + "job-name": "Име посла", + "job-queue": "Посао по реду", + "last-run": "Последње покретање", + "max-concurrent": "Паралелно", + "memory-usage": "Искоришћеност меморије", + "migrate-all-to-filesystem": "Пресели све у локално складиште", + "migrate-all-to-gridfs": "Пресели све и издели у GridFS", + "migrate-all-to-s3": "Пресели све у Amazon S3 облак", + "migrated-attachments": "Пресељена предметна грађа", + "migration-batch-size": "Ширина захвата", + "migration-batch-size-description": "Број јединица предметне грађе који ће бити обрађен при сваком пролазу (1-100)", + "migration-cpu-threshold": "Граница искоришћења процесора (%)", + "migration-cpu-threshold-description": "Направи предах када заузеће процесора досегне ове проценте (10-90)", + "migration-delay-ms": "Задршка (ms)", + "migration-delay-ms-description": "Задршка између пролаза изражена у милисекундама (100-10000)", + "migration-detector": "Детектор", + "migration-info-text": "Преслагање базе података се изводи само једном и то поправља брзину. Ова радња се изводи у позадини чак иако одете.", + "migration-log": "Записник из обнове", + "migration-markers": "Обележја обнове", + "migration-resume-failed": "Није успео наставак обнове", + "migration-resumed": "Обнова је настављена", + "migration-steps": "Кораци у обнови", + "migration-warning-text": "Предлажемо да не затварате прозор током обнове. Чак и тада процес ће бити изведен у позадини али све може дуже да траје.", + "monitoring-export-failed": "Не могу да извезем надзорне податаке", + "monitoring-refresh-failed": "Не могу да освежим надзорне податке", + "next": "Следеће", + "next-run": "Наредни покрет", + "of": "од", + "operation-type": "Врста радње", + "overall-progress": "Измерени напредак", + "page": "Страна", + "pause-migration": "Направи предах", + "previous": "Претходна", + "refresh": "Освежи", + "refresh-monitoring": "Најновији подаци са надзора", + "remaining-attachments": "Преостала предметна грађа", + "resume-migration": "Настави обнову", + "run-once": "Покрени једном", + "s3-attachments": "Предметна грађа у Amazon S3 облаку", + "s3-size": "Amazon S3 заузеће", + "s3-storage": "S3", + "scanning-status": "Изучено стање", + "schedule": "Распоред", + "search-boards-or-operations": "Претрага списа или радњи...", + "show-list-on-minicard": "Прикажи део поступка на омоту", + "showing": "Приказујем", + "start-test-operation": "Start Test Operation", + "start-time": "Покрени штоперицу", + "step-progress": "Појединачни напредак", + "stop-migration": "Заустави обнову", + "storage-distribution": "Расподела у складишту", + "system-resources": "Системска снага", + "total-attachments": "Број јединица предметне грађе", + "total-operations": "Укупан број радњи", + "total-size": "Укупна величина", + "unmigrated-boards": "Необновљени списи", + "weight": "Оптерећење", + "idle": "Стање мировања", + "complete": "Посао је успешно обављен", + "cron": "Периодични послови" } diff --git a/imports/i18n/data/sv.i18n.json b/imports/i18n/data/sv.i18n.json index 52e6cd0ca..fa54b9991 100644 --- a/imports/i18n/data/sv.i18n.json +++ b/imports/i18n/data/sv.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "raderade kommentar %s", "activity-receivedDate": "redigerade mottaget datum till %s av %s", "activity-startDate": "redigerade startdatum till %s av %s", + "allboards.starred": " Stjärnmärkt", + "allboards.templates": "Mallar", + "allboards.remaining": "Återstående", + "allboards.workspaces": "Arbetsytor", + "allboards.add-workspace": "Lägg till arbetsyta", + "allboards.add-workspace-prompt": "Arbetsytans namn", + "allboards.add-subworkspace": "Lägg till underarbetsyta", + "allboards.add-subworkspace-prompt": "Underarbetsytans namn", + "allboards.edit-workspace": "Redigera arbetsyta", + "allboards.edit-workspace-name": "Arbetsytans namn", + "allboards.edit-workspace-icon": "Arbetsytans ikon (markdown)", + "multi-selection-active": "Klicka i kryssrutor för att välja tavlor", "activity-dueDate": "redigerade förfallodag till %s av %s", "activity-endDate": "redigerade slutdatum till %s av %s", "add-attachment": "Lägg till bilaga", @@ -190,7 +202,9 @@ "board-view-collapse": "Fäll ihop", "board-view-gantt": "Gantt", "board-view-lists": "Listor", - "bucket-example": "Som t.ex. \"Kalasplanering\"", + "bucket-example": " Som till exempel \"Bucket List\"", + "calendar-previous-month-label": " Föregående månad", + "calendar-next-month-label": " Nästa månad", "cancel": "Avbryt", "card-archived": "Detta kort är flyttat till arkiv.", "board-archived": "Den här tavlan är flyttad till arkiv.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Första kortets titel\", \"description\":\"Första kortets beskrivning\"}, {\"title\":\"Andra kortets titel\",\"description\":\"Andra kortets beskrivning\"},{\"title\":\"Sista kortets titel\",\"description\":\"Sista kortets beskrivning\"} ]", "create": "Skapa", "createBoardPopup-title": "Skapa tavla", + "createTemplateContainerPopup-title": "Lägg till från mall", "chooseBoardSourcePopup-title": "Importera tavla", "createLabelPopup-title": "Skapa etikett", "createCustomField": "Skapa fält", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Anpassade fält", "date": "Datum", + "date-format": "Datumformat", + "date-format-yyyy-mm-dd": "ÅÅÅÅ-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-ÅÅÅÅ", + "date-format-mm-dd-yyyy": "MM-DD-ÅÅÅÅ", "decline": "Neka", "default-avatar": "Standard avatar", "delete": "Ta bort", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Redigera notis", "editProfilePopup-title": "Redigera profil", "email": "E-post", + "email-address": "E-postadress", "email-enrollAccount-subject": "Ett konto skapat för dig på __siteName__", "email-enrollAccount-text": "Hej __user__,\n\nFör att börja använda tjänsten, klicka på länken nedan.\n\n__url__\n\nTack!", "email-fail": "Sändning av e-post misslyckades", @@ -631,9 +651,9 @@ "upload": "Ladda upp", "upload-avatar": "Ladda upp en avatar", "uploaded-avatar": "Laddade upp en avatar", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "Laddar upp filer", + "upload-failed": "Uppladdning misslyckades", + "upload-completed": "Uppladdning slutförd", "custom-top-left-corner-logo-image-url": "Länk till anpassad logotypbild", "custom-top-left-corner-logo-link-url": "Länk för anpassad logotyp", "custom-top-left-corner-logo-height": "Anpassad logotyphöjd uppe till vänster. Standard: 27", @@ -748,6 +768,8 @@ "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?", "delete-board": "Ta bort tavla", + "delete-duplicate-lists": "Ta bort dubblettlistor", + "delete-duplicate-lists-confirm": "Är du säker? Detta kommer att ta bort alla dubblettlistor som har samma namn och inte innehåller några kort.", "default-subtasks-board": "Deluppgifter för __board__ board", "default": "Standard", "defaultdefault": "Standard", @@ -755,7 +777,7 @@ "subtask-settings": "Deluppgift inställningar", "card-settings": "Kortinställningar", "minicard-settings": "Minikort inställningar", - "boardSubtaskSettingsPopup-title": "Tavelinställningar för deluppgifter", + "boardSubtaskSettingsPopup-title": "Deluppgift inställningar", "boardCardSettingsPopup-title": "Kortinställningar", "boardMinicardSettingsPopup-title": "Minikort inställningar", "deposit-subtasks-board": "Lägg till deluppgifter till denna tavla:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Jag", "dueCardsViewChange-choice-all": "Alla användare", "dueCardsViewChange-choice-all-description": "Visar alla oklara kort med *förfallo* datum från tavlor som användaren har tillgång till.", + "dueCards-noResults-title": " Inga kort med förfallodatum hittades", + "dueCards-noResults-description": "Du har inga kort med förfallodatum just nu.", "broken-cards": "Trasiga kort", "board-title-not-found": "Tavla '%s' hittades inte.", "swimlane-title-not-found": "Simbana '%s' hittades inte.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "Användaren är aktiv – klicka för att inaktivera", "admin-people-user-inactive": "Användaren är inaktiv – klicka för att aktivera", "accounts-lockout-all-users-unlocked": "Alla låsta användare har låsts upp", - "accounts-lockout-unlock-all": "Lås upp alla" + "accounts-lockout-unlock-all": "Lås upp alla", + "active-cron-jobs": "Aktiva schemalagda jobb", + "add-cron-job": " Lägg till schemalagt jobb", + "add-cron-job-placeholder": "Funktionen för att lägga till schemalagda jobb kommer snart", + "attachment-storage-configuration": "Konfiguration av fillagringsplats", + "attachments-path": " Sökväg för bilagor", + "attachments-path-description": "Sökväg där bifogade filer lagras", + "avatars-path": "Sökväg för avatarer", + "avatars-path-description": "Sökväg där avatarfiler lagras", + "board-archive-failed": "Misslyckades att schemalägga arkivering av tavla", + "board-archive-scheduled": "Tavlans arkivering har schemalagts", + "board-backup-failed": "Misslyckades med att schemalägga säkerhetskopiering av tavlan", + "board-backup-scheduled": "Säkerhetskopiering av tavlan har schemalagts", + "board-cleanup-failed": "Misslyckades med att schemalägga rensning av tavlan", + "board-cleanup-scheduled": "Rensning av tavlan har schemalagts", + "board-operations": "Tavlans åtgärder", + "cron-jobs": "Schemalagda jobb", + "cron-migrations": "Schemalagda migreringar", + "cron-job-delete-confirm": "Är du säker på att du vill ta bort det här schemalagda jobbet?", + "cron-job-delete-failed": "Misslyckades med att ta bort schemalagt jobb", + "cron-job-deleted": "Schemalagt jobb borttaget", + "cron-job-pause-failed": "Misslyckades med att pausa schemalagt jobb", + "cron-job-paused": "Schemalagt jobb pausat", + "filesystem-path-description": "Basväg för fillagring", + "gridfs-enabled": "GridFS aktiverat", + "gridfs-enabled-description": "Använd MongoDB GridFS för fillagring", + "migration-pause-failed": "Misslyckades med att pausa migreringar", + "migration-paused": "Migreringar har pausats", + "migration-progress": "Migreringsförlopp", + "migration-start-failed": "Misslyckades med att starta migreringar", + "migration-started": "Migreringar har startats", + "migration-status": "Migreringsstatus", + "migration-stop-confirm": "Är du säker på att du vill stoppa alla migreringar?", + "migration-stop-failed": "Misslyckades med att stoppa migreringar", + "migration-stopped": "Migreringar har stoppats", + "mongodb-gridfs-storage": "MongoDB GridFS-lagring", + "pause-all-migrations": "Pausa alla migreringar", + "s3-access-key": "S3-åtkomstnyckel", + "s3-access-key-description": "AWS S3-åtkomstnyckel för autentisering", + "s3-access-key-placeholder": "Ange S3-åtkomstnyckel", + "s3-bucket": "S3-hink", + "s3-bucket-description": "Namn på S3-hink för lagring av filer", + "s3-connection-failed": "S3-anslutning misslyckades", + "s3-connection-success": "S3-anslutning lyckades", + "s3-enabled": "S3 aktiverat", + "s3-enabled-description": "Använd AWS S3 eller MinIO för fillagring", + "s3-endpoint": "S3-endpunkt", + "s3-endpoint-description": "S3-endpunkts-URL (t.ex. s3.amazonaws.com eller minio.example.com)", + "s3-minio-storage": "S3/MinIO-lagring", + "s3-port": "S3-port", + "s3-port-description": "Portnummer för S3-endpunkt", + "s3-region": "S3-region", + "s3-region-description": "AWS S3-region (t.ex. us-east-1)", + "s3-secret-key": "S3-hemlig nyckel", + "s3-secret-key-description": "AWS S3-hemlig nyckel för autentisering", + "s3-secret-key-placeholder": "Ange S3-hemlig nyckel", + "s3-secret-key-required": "S3-hemlig nyckel krävs", + "s3-settings-save-failed": "Misslyckades med att spara S3-inställningar", + "s3-settings-saved": "S3-inställningar har sparats", + "s3-ssl-enabled": "S3 SSL aktiverat", + "s3-ssl-enabled-description": "Använd SSL/TLS för S3-anslutningar", + "save-s3-settings": "Spara S3-inställningar", + "schedule-board-archive": "Schemalägg tavlarkivering", + "schedule-board-backup": "Schemalägg säkerhetskopiering av tavlan", + "schedule-board-cleanup": "Schemalägg rensning av tavlan", + "scheduled-board-operations": "Schemalagda tavlans åtgärder", + "start-all-migrations": "Starta alla migreringar", + "stop-all-migrations": "Stoppa alla migreringar", + "test-s3-connection": "Testa S3-anslutning", + "writable-path": "Skrivbar sökväg", + "writable-path-description": "Baskatalogsökväg för fillagring", + "add-job": "Lägg till jobb", + "attachment-migration": "Migrering av bilagor", + "attachment-monitoring": "Övervakning av bilagor", + "attachment-settings": "Bilageinställningar", + "attachment-storage-settings": " Lagringsinställningar", + "automatic-migration": "Automatisk migrering", + "back-to-settings": "Tillbaka till inställningar", + "board-id": "Tavlans ID", + "board-migration": "Tavelmigration", + "board-migrations": "Migrering av tavlor", + "card-show-lists-on-minicard": "Visa listor på minikort", + "comprehensive-board-migration": "Fullständig migration av alla tavlor ", + "comprehensive-board-migration-description": "Utför omfattande kontroller och korrigeringar för tavlans dataintegritet, inklusive listordning, kortpositioner och swimlane-struktur.", + "delete-duplicate-empty-lists-migration": "Ta bort duplicerade tomma listor", + "delete-duplicate-empty-lists-migration-description": "Tar säkert bort tomma duplicerade listor. Tar endast bort listor som inte har några kort OCH där det finns en annan lista med samma titel som innehåller kort.", + "lost-cards": "Förlorade kort ", + "lost-cards-list": "Återställda objekt", + "restore-lost-cards-migration": "Återställ förlorade kort", + "restore-lost-cards-migration-description": "Hittar och återställer kort och listor som saknar simbaneid eller listId. Skapar en 'Förlorade kort'-simbana för att göra alla förlorade objekt synliga igen.", + "restore-all-archived-migration": "Återställ från Arkiv", + "restore-all-archived-migration-description": "Återställer alla arkiverade swimlanes, listor och kort. Korrigerar automatiskt alla saknade simbaneId eller listId för att göra objekt synliga.", + "fix-missing-lists-migration": "Fixa saknade listor", + "fix-missing-lists-migration-description": "Upptäcker och reparerar saknade eller korrupta listor i tavlans struktur.", + "fix-avatar-urls-migration": "Fixa avatar-URL:er", + "fix-avatar-urls-migration-description": "Uppdaterar avatar-URL:er för tavlans medlemmar till att använda rätt lagrings-backend och fixar trasiga avatar-referenser.", + "fix-all-file-urls-migration": "Fixa alla fil-URL:er", + "fix-all-file-urls-migration-description": "Uppdaterar alla URL:er för filbilagor på denna tavla till att använda rätt lagrings-backend och fixar trasiga filreferenser.", + "migration-needed": "Migrering krävs", + "migration-complete": "Avslutad", + "migration-running": "Körs...", + "migration-successful": "Migrering slutförd", + "migration-failed": "Migrering misslyckades", + "migrations": "Migreringar", + "migrations-admin-only": "Endast tavlans administratörer kan köra migreringar", + "migrations-description": "Kör dataintegritetskontroller och reparationer för denna tavla. Varje migrering kan utföras individuellt.", + "no-issues-found": "Inga problem hittades", + "run-migration": "Kör migrering", + "run-comprehensive-migration-confirm": "Detta kommer att utföra en omfattande migrering för att kontrollera och fixa tavlans dataintegritet. Detta kan ta en liten stund. Fortsätt?", + "run-delete-duplicate-empty-lists-migration-confirm": "Detta kommer först att konvertera alla delade listor till listor per simbana, och sedan ta bort tomma listor som har en dubblettlista med samma titel som innehåller kort. Endast överflödiga tomma listor kommer att tas bort. Fortsätt?", + "run-restore-lost-cards-migration-confirm": "Detta kommer att skapa en 'Förlorade kort'-simbana och återställa alla kort och listor som saknar simbaneId eller listId. Detta påverkar endast icke-arkiverade objekt. Fortsätt?", + "run-restore-all-archived-migration-confirm": "Detta kommer att återställa ALLA arkiverade simbanor, listor och kort, vilket gör dem synliga igen. Alla objekt med saknade ID:n kommer att fixas automatiskt. Detta kan inte enkelt ångras. Fortsätt?", + "run-fix-missing-lists-migration-confirm": "Detta kommer att upptäcka och reparera saknade eller korrupta listor i tavlans struktur. Fortsätt?", + "run-fix-avatar-urls-migration-confirm": "Detta kommer att uppdatera avatar-URL:er för tavlans medlemmar till att använda rätt lagrings-backend. Fortsätt?", + "run-fix-all-file-urls-migration-confirm": "Detta kommer att uppdatera alla URL:er för filbilagor på denna tavla till att använda rätt lagrings-backend. Fortsätt?", + "restore-lost-cards-nothing-to-restore": "Inga förlorade simbanor, listor eller kort att återställa", + + "migration-progress-title": "Tavlans migrering pågår", + "migration-progress-overall": "Övergripande förlopp", + "migration-progress-current-step": "Nuvarande steg", + "migration-progress-status": "Status", + "migration-progress-details": "Detaljer", + "migration-progress-note": "Vänta medan vi migrerar din tavla till den senaste strukturen...", + + "step-analyze-board-structure": "Analysera tavlans struktur", + "step-fix-orphaned-cards": "Fixa övergivna kort", + "step-convert-shared-lists": "Konvertera delade listor", + "step-ensure-per-swimlane-lists": "Säkerställ listor per simbana", + "step-validate-migration": "Validera migrering", + "step-fix-avatar-urls": "Fixa avatar-URL:er", + "step-fix-attachment-urls": "Fixa bilage-URL:er", + "step-analyze-lists": "Analysera listor", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Uppdatera kort", + "step-finalize": "Slutför", + "step-delete-duplicate-empty-lists": "Ta bort duplicerade tomma listor", + "step-ensure-lost-cards-swimlane": "Säkerställ simbana för förlorade kort", + "step-restore-lists": "Återställ listor", + "step-restore-cards": "Återställ kort", + "step-restore-swimlanes": "Återställ simbanor", + "step-fix-missing-ids": "Fixa saknade ID:n", + "step-scan-users": "Kontrollerar tavlans medlemsavatarer", + "step-scan-files": "Kontrollerar tavlans filbilagor", + "step-fix-file-urls": "Fixar fil-URL:er", + "cleanup": "Rensning", + "cleanup-old-jobs": "Rensa gamla jobb", + "completed": "Avslutad", + "conversion-info-text": "Denna konvertering utförs en gång per tavla och förbättrar prestandan. Ni kan fortsätta använda tavlan som vanligt.", + "converting-board": "Konverterar tavla", + "converting-board-description": "Konverterar tavlans struktur för förbättrad funktionalitet. Detta kan ta en liten stund.", + "cpu-cores": "CPU-kärnor", + "cpu-usage": "CPU-användning", + "current-action": "Nuvarande åtgärd", + "database-migration": "Databas­migrering", + "database-migration-description": "Uppdaterar databasstrukturen för förbättrad funktionalitet och prestanda. Denna process kan ta flera minuter.", + "database-migrations": "Databas­migreringar", + "days-old": "Dagar gammal", + "duration": "Varaktighet", + "errors": "Fel", + "estimated-time-remaining": "Beräknad återstående tid", + "every-1-day": "Var 1 dag", + "every-1-hour": "Var 1 timme", + "every-1-minute": "Var 1 minut", + "every-10-minutes": "Var 10 minuter", + "every-30-minutes": "Var 30 minuter", + "every-5-minutes": "Var 5 minuter", + "every-6-hours": "Var 6 timmar", + "export-monitoring": "Exportövervakning", + "filesystem-attachments": "Filssystem-bilagor", + "filesystem-size": "Filssystemstorlek", + "filesystem-storage": "Filssystemlagring", + "force-board-scan": "Tvinga tavelskanning", + "gridfs-attachments": "GridFS-bilagor", + "gridfs-size": "GridFS-storlek", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Göm lista på minikort", + "idle-migration": "Inaktiv migrering", + "job-description": "Jobbeskrivning", + "job-details": "Jobbdetaljer", + "job-name": "Jobbnamn", + "job-queue": "Jobbkö", + "last-run": "Senaste körning", + "max-concurrent": "Max samtidigt", + "memory-usage": "Minnesanvändning", + "migrate-all-to-filesystem": "Migrera allt till filsystem", + "migrate-all-to-gridfs": "Migrera allt till GridFS", + "migrate-all-to-s3": "Migrera allt till S3", + "migrated-attachments": "Migrerade bilagor", + "migration-batch-size": "Batchstorlek", + "migration-batch-size-description": "Antal bilagor att bearbeta i varje batch (1-100)", + "migration-cpu-threshold": "CPU-tröskel (%)", + "migration-cpu-threshold-description": "Pausa migreringen när CPU-användningen överstiger denna procentsats (10-90)", + "migration-delay-ms": "Fördröjning (ms)", + "migration-delay-ms-description": "Fördröjning mellan batchar i millisekunder (100-10000)", + "migration-detector": "Migreringsdetektor", + "migration-info-text": "Databas­migreringar utförs en gång och förbättrar systemets prestanda. Processen fortsätter i bakgrunden även om du stänger din webbläsare.", + "migration-log": "Migreringslogg", + "migration-markers": "Migreringsmarkörer", + "migration-resume-failed": "Misslyckades med att återuppta migrering", + "migration-resumed": "Migrering återupptogs", + "migration-steps": "Migreringssteg", + "migration-warning-text": "Vänligen stäng inte din webbläsare under migreringen. Processen fortsätter i bakgrunden men kan ta längre tid att slutföra.", + "monitoring-export-failed": "Misslyckades med att exportera övervakningsdata", + "monitoring-refresh-failed": "Misslyckades med att uppdatera övervakningsdata", + "next": "Nästa", + "next-run": "Nästa körning", + "of": "av", + "operation-type": "Operationstyp", + "overall-progress": "Övergripande förlopp", + "page": "Sida", + "pause-migration": "Pausa migrering", + "previous": "Föregående", + "refresh": "Uppdatera", + "refresh-monitoring": "Uppdatera övervakning", + "remaining-attachments": "Återstående bilagor", + "resume-migration": "Återuppta migrering", + "run-once": "Kör en gång", + "s3-attachments": "S3-bilagor", + "s3-size": "S3-storlek", + "s3-storage": "S3", + "scanning-status": "Skanningsstatus", + "schedule": "Schema", + "search-boards-or-operations": "Sök tavlor eller operationer...", + "show-list-on-minicard": "Visa lista på minikort", + "showing": "Visar", + "start-test-operation": "Starta testoperation", + "start-time": "Starttid", + "step-progress": "Stegförlopp", + "stop-migration": "Stoppa migrering", + "storage-distribution": "Lagringsdistribution", + "system-resources": "Systemresurser", + "total-attachments": "Totala bilagor", + "total-operations": "Totala operationer", + "total-size": "Total storlek", + "unmigrated-boards": "Okonverterade tavlor", + "weight": "Vikt", + "idle": "Inaktiv", + "complete": "Avslutad", + "cron": "Cron" } diff --git a/imports/i18n/data/sw.i18n.json b/imports/i18n/data/sw.i18n.json index 5efd9cd67..1e7bce7ae 100644 --- a/imports/i18n/data/sw.i18n.json +++ b/imports/i18n/data/sw.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ta.i18n.json b/imports/i18n/data/ta.i18n.json index 1d5d1164a..fd711f921 100644 --- a/imports/i18n/data/ta.i18n.json +++ b/imports/i18n/data/ta.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "உருவாக்கு", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "நாள்", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "மின் அஞ்சல்", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/te-IN.i18n.json b/imports/i18n/data/te-IN.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/te-IN.i18n.json +++ b/imports/i18n/data/te-IN.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/th.i18n.json b/imports/i18n/data/th.i18n.json index 726dbe38b..0ec733bbe 100644 --- a/imports/i18n/data/th.i18n.json +++ b/imports/i18n/data/th.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "รายการ", - "bucket-example": "ตัวอย่างเช่น “ระบบที่ต้องทำ”", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "ยกเลิก", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "สร้าง", "createBoardPopup-title": "สร้างบอร์ด", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "สร้างป้ายกำกับ", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "วันที่", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "ปฎิเสธ", "default-avatar": "ภาพเริ่มต้น", "delete": "ลบ", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "แก้ไขการแจ้งเตือน", "editProfilePopup-title": "แก้ไขโปรไฟล์", "email": "อีเมล์", + "email-address": "Email Address", "email-enrollAccount-subject": "บัญชีคุณถูกสร้างใน __siteName__", "email-enrollAccount-text": "สวัสดี __user__,\n\nเริ่มใช้บริการง่าย ๆ , ด้วยการคลิกลิงค์ด้านล่าง.\n\n__url__\n\n ขอบคุณค่ะ", "email-fail": "การส่งอีเมล์ล้มเหลว", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/tk_TM.i18n.json b/imports/i18n/data/tk_TM.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/tk_TM.i18n.json +++ b/imports/i18n/data/tk_TM.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/tlh.i18n.json b/imports/i18n/data/tlh.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/tlh.i18n.json +++ b/imports/i18n/data/tlh.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/tr.i18n.json b/imports/i18n/data/tr.i18n.json index f6e3adecf..d413e318b 100644 --- a/imports/i18n/data/tr.i18n.json +++ b/imports/i18n/data/tr.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "%s yorum silindi", "activity-receivedDate": "alma tarihi için düzenlendi%s", "activity-startDate": "başlangıç tarihi %s, %s olarak düzenlendi", + "allboards.starred": "Starred", + "allboards.templates": "Şablonlar", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "bitiş tarihi %s / %s olarak düzenlendi", "activity-endDate": "son bitiş tarihi %s, %s olarak düzenlendi", "add-attachment": "Ek Ekle", @@ -90,8 +102,8 @@ "set-list-width": "Genişlik Ata", "set-list-width-value": "En Az & En Çok Genişlik (piksel) Ata ", "list-width-error-message": "Liste genişliği 100'den büyük sayısal bir değer olmalı", - "keyboard-shortcuts-enabled": "Keyboard shortcuts enabled. Click to disable.", - "keyboard-shortcuts-disabled": "Keyboard shortcuts disabled. Click to enable.", + "keyboard-shortcuts-enabled": "Klavye kısayolları etkin. Devre dışı bırakmak için tıklayın.\n ", + "keyboard-shortcuts-disabled": "Klavye kısayolları devre dışı. Etkinleştirmek için tıklayın.", "setSwimlaneHeightPopup-title": "Kulvar Uzunluğunu Ayarla", "set-swimlane-height": "Kulvar Uzunluğunu Ayarla", "set-swimlane-height-value": "Kulvar Uzunluğu (piksel)", @@ -106,7 +118,7 @@ "add-cover": "Mini karta kapak resmi ekle", "add-label": "Etiket Ekle", "add-list": "Liste Ekle", - "add-after-list": "Add After List", + "add-after-list": "Listeden Sonra Ekle", "add-members": "Üye ekle", "added": "Eklendi", "addMemberPopup-title": "Üyeler", @@ -125,7 +137,7 @@ "archive": "Arşive Taşı", "archive-all": "Hepsini Arşive Taşı", "archive-board": "Panoyu Arşive Taşı", - "archive-board-confirm": "Are you sure you want to archive this board?", + "archive-board-confirm": "Bu panoyu arşivlemek istediğinizden emin misiniz?", "archive-card": "Kartı Arşive Taşı", "archive-list": "Listeyi Arşive Taşı", "archive-swimlane": "Kulvarı Arşive Taşı", @@ -162,7 +174,7 @@ "show-board_members-avatar": "Show Board members avatars", "board-nb-stars": "%s yıldız", "board-not-found": "Pano bulunamadı", - "board-private-info": "This board will be private.", + "board-private-info": "Bu pano özel olacak.", "board-public-info": "Bu pano genele açılacaktır.", "board-drag-drop-reorder-or-click-open": "Tahta ikonlarını yeniden sıralamak için sürükleyip bırakın. Tahtayı açmak için tahta ikonuna tıklayın.", "boardChangeColorPopup-title": "Pano arkaplan rengini değiştir", @@ -177,20 +189,22 @@ "boardChangeViewPopup-title": "Pano Görünümü", "boards": "Panolar", "board-view": "Pano Görünümü", - "desktop-mode": "Desktop Mode", - "mobile-mode": "Mobile Mode", - "mobile-desktop-toggle": "Toggle between Mobile and Desktop Mode", - "zoom-in": "Zoom In", - "zoom-out": "Zoom Out", - "click-to-change-zoom": "Click to change zoom level", - "zoom-level": "Zoom Level", - "enter-zoom-level": "Enter zoom level (50-300%):", + "desktop-mode": "Masaüstü Modu", + "mobile-mode": "Mobil Modu", + "mobile-desktop-toggle": "Mobil ve Masaüstü Modu arasında geçiş yapın", + "zoom-in": "Yakınlaştır", + "zoom-out": "Uzaklaştır", + "click-to-change-zoom": "Yakınlaştırma düzeyini değiştirmek için tıklayın", + "zoom-level": "Yakınlaştırma düzeyi", + "enter-zoom-level": "Yakınlaştırma düzeyini girin (50-300%):", "board-view-cal": "Takvim", "board-view-swimlanes": "Kulvarlar", "board-view-collapse": "Katla", "board-view-gantt": "Gant Şeması", "board-view-lists": "Listeler", - "bucket-example": "Örn: \"Marketten Alacaklarım\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "İptal", "card-archived": "Bu kart arşive taşındı.", "board-archived": "Bu pano arşive taşındı.", @@ -275,9 +289,9 @@ "checklists": "Yapılacak Listeleri", "click-to-star": "Bu panoyu yıldızlamak için tıkla.", "click-to-unstar": "Bu panunun yıldızını kaldırmak için tıkla.", - "click-to-enable-auto-width": "Auto list width disabled. Click to enable.", - "click-to-disable-auto-width": "Auto list width enabled. Click to disable.", - "auto-list-width": "Auto list width", + "click-to-enable-auto-width": "Otomatik liste genişliği devre dışı. Etkinleştirmek için tıklayın.", + "click-to-disable-auto-width": "Otomatik liste genişliği etkin. Devre dışı bırakmak için tıklayın.", + "auto-list-width": "Otomatik liste genişliği", "clipboard": "Yapıştır veya sürükleyip bırak", "close": "Kapat", "close-board": "Panoyu kapat", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"İlk kart başlığı\", \"description\":\"İlk kart açıklaması\"}, {\"title\":\"İkinci kart başlığı\",\"description\":\"İkinci kart açıklaması\"},{\"title\":\"Son kart başlığı\",\"description\":\"Son kart açıklaması\"} ]", "create": "Oluştur", "createBoardPopup-title": "Pano Oluşturma", + "createTemplateContainerPopup-title": "Şablon Konteyner Ekle", "chooseBoardSourcePopup-title": "Panoyu içe aktar", "createLabelPopup-title": "Etiket Oluşturma", "createCustomField": "Alanı yarat", @@ -354,6 +369,10 @@ "custom-field-text": "Metin", "custom-fields": "Özel alanlar", "date": "Tarih", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Reddet", "default-avatar": "Varsayılan avatar", "delete": "Sil", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Bildirimi değiştir", "editProfilePopup-title": "Profili Düzenle", "email": "E-posta", + "email-address": "Email Address", "email-enrollAccount-subject": "Hesabınız __siteName__ üzerinde oluşturuldu", "email-enrollAccount-text": "Merhaba __user__,\n\nBu servisi kullanmaya başlamak için aşağıdaki linke tıklamalısın:\n\n__url__\n\nTeşekkürler.", "email-fail": "E-posta gönderimi başarısız", @@ -392,14 +412,14 @@ "email-sent": "E-posta gönderildi", "email-verifyEmail-subject": "__siteName__ üzerindeki e-posta adresini doğrulama", "email-verifyEmail-text": "Merhaba __user__,\n\nHesap e-posta adresini doğrulamak için aşağıdaki linke tıklaman yeterli.\n\n__url__\n\nTeşekkürler.", - "enable-vertical-scrollbars": "Enable vertical scrollbars", + "enable-vertical-scrollbars": "Dikey kaydırma çubuklarını etkinleştir", "enable-wip-limit": "Devam Eden İş Sınırını Aç", "error-board-doesNotExist": "Pano bulunamadı", "error-board-notAdmin": "Bu işlemi yapmak için pano yöneticisi olmalısın.", "error-board-notAMember": "Bu işlemi yapmak için panoya üye olmalısın.", "error-json-malformed": "Girilen metin geçerli bir JSON formatında değil", "error-json-schema": "Girdiğin JSON metni tüm bilgileri doğru biçimde barındırmıyor", - "error-csv-schema": "Your CSV(Comma Separated Values)/TSV (Tab Separated Values) does not include the proper information in the correct format ", + "error-csv-schema": "CSV (Virgülle Ayrılmış Değerler)/TSV (Sekmeyle Ayrılmış Değerler) dosyanız doğru biçimde uygun bilgileri içermiyor", "error-list-doesNotExist": "Liste bulunamadı", "error-user-doesNotExist": "Kullanıcı bulunamadı", "error-user-notAllowSelf": "Kendi kendini davet edemezsin", @@ -441,7 +461,7 @@ "filter-due-next-week": "Due next week", "filter-due-tomorrow": "Son tarihi yarın", "list-filter-label": "Listeyi Başlığa Göre Filtrele", - "filter-clear": "Clear filter", + "filter-clear": "Filtreyi temizle", "filter-labels-label": "Etikete göre filtrele", "filter-no-label": "Etiket yok", "filter-member-label": "Üyeye göre filtrele", @@ -460,7 +480,7 @@ "advanced-filter-description": "Gelişmiş Filtre, aşağıdaki operatörleri içeren bir dize yazmaya izin verir: == != <= >= && || ( ) Operatörler arasında ayırıcı olarak boşluk kullanılır. Adlarını ve değerlerini yazarak tüm Özel Alanlar için filtre uygulayabilirsiniz. Örneğin: Alan1 == Değer1. Not: Alanlar veya değerler boşluk içeriyorsa, bunları tek tırnak içine almanız gerekir. Örneğin: 'Alan 1' == 'Değer 1'. Tek kontrol karakterlerinin (' \\\\/) atlanması için \\\\ kullanabilirsiniz. Örneğin: Alan1 == Ben. Ayrıca birden fazla koşulu birleştirebilirsiniz. Örneğin: F1 == V1 || F1 == V2. Normalde tüm operatörler soldan sağa doğru yorumlanır. Parantez koyarak sırayı değiştirebilirsiniz. Örneğin: F1 == V1 && ( F2 == V2 || F2 == V3 ). Ayrıca normal ifadeyi kullanarak metin alanlarında arama yapabilirsiniz: F1 == /Tes.*/i", "fullname": "Ad Soyad", "header-logo-title": "Panolar sayfanıza geri dön.", - "show-activities": "Show Activities", + "show-activities": "Etkinlikleri gör", "headerBarCreateBoardPopup-title": "Pano Oluşturma", "home": "Ana Sayfa", "import": "İçeri aktar", @@ -596,7 +616,7 @@ "shortcut-clear-filters": "Tüm filtreleri temizle", "shortcut-close-dialog": "Diyaloğu kapat", "shortcut-filter-my-cards": "Kartlarımı filtrele", - "shortcut-filter-my-assigned-cards": "Filter my assigned cards", + "shortcut-filter-my-assigned-cards": "Atanmış kartlarımı filtrele", "shortcut-show-shortcuts": "Kısayollar listesini getir", "shortcut-toggle-filterbar": "Filtre kenar çubuğunu aç/kapa", "shortcut-toggle-searchbar": "Arama Kenar Çubuğunu Aç/Kapat", @@ -631,9 +651,9 @@ "upload": "Yükle", "upload-avatar": "Avatar yükle", "uploaded-avatar": "Avatar yüklendi", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "Dosyaları yüklüyor", + "upload-failed": "Yükleme hata verdi", + "upload-completed": "Yükleme tamamlandı", "custom-top-left-corner-logo-image-url": "Özel Sol Üst Köşe Logo Resmi URL'si", "custom-top-left-corner-logo-link-url": "Özel Sol Üst Köşe Logo Bağlantı URL'si", "custom-top-left-corner-logo-height": "Özel Üst Sol Köşe Logo Yüksekliği. Varsayılan: 27", @@ -748,6 +768,8 @@ "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?", "delete-board": "Panoyu Sil", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "__board__ panosu için alt görevler", "default": "Varsayılan", "defaultdefault": "Varsayılan", @@ -755,7 +777,7 @@ "subtask-settings": "Alt Görev ayarları", "card-settings": "Kart ayarları", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Pano alt görev ayarları", + "boardSubtaskSettingsPopup-title": "Alt Görev ayarları", "boardCardSettingsPopup-title": "Kart ayarları", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Alt görevleri bu panoda sakla:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Ben mi", "dueCardsViewChange-choice-all": "Tüm Kullanıcılar", "dueCardsViewChange-choice-all-description": "Kullanıcının iznine sahip olduğu panolardan *Son* tarihi olan tüm eksik kartları gösterir.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Kırık Kartlar", "board-title-not-found": "'%s' Pano bulunmadı.", "swimlane-title-not-found": "Yüzme kulvarı '%s'bulunamadı.", @@ -1124,7 +1148,7 @@ "label-names": "Etiket İsimleri", "archived-at": "Şurada arşivlendi", "sort-cards": "Kartları Sırala", - "sort-is-on": "Sort is on", + "sort-is-on": "Sıralama açık", "cardsSortPopup-title": "Kartları Sırala", "due-date": "Bitiş Tarihi", "server-error": "Server hatası", @@ -1266,10 +1290,10 @@ "newTranslationPopup-title": "New custom translation string", "editTranslationPopup-title": "Edit custom translation string", "settingsTranslationPopup-title": "Delete this custom translation string?", - "translation": "Translation", + "translation": "Çeviri", "text": "Metin", - "translation-text": "Translation text", - "show-subtasks-field": "Show subtasks field", + "translation-text": "Çeviri metni", + "show-subtasks-field": "Alt görevlerin alanını göster", "show-week-of-year": "Show week of year (ISO 8601)", "convert-to-markdown": "Convert to markdown", "import-board-zip": "Add .zip file that has board JSON files, and board name subdirectories with attachments", @@ -1277,17 +1301,17 @@ "uncollapse": "Uncollapse", "hideCheckedChecklistItems": "Hide checked checklist items", "hideAllChecklistItems": "Hide all checklist items", - "support": "Support", - "supportPopup-title": "Support", - "accessibility": "Accessibility", - "accessibility-page-enabled": "Accessibility page enabled", - "accessibility-info-not-added-yet": "Accessibility info has not been added yet", - "accessibility-title": "Accessibility title", - "accessibility-content": "Accessibility content", - "accounts-lockout-settings": "Brute Force Protection Settings", - "accounts-lockout-info": "These settings control how login attempts are protected against brute force attacks.", - "accounts-lockout-known-users": "Settings for known users (correct username, wrong password)", - "accounts-lockout-unknown-users": "Settings for unknown users (non-existent username)", + "support": "Destek", + "supportPopup-title": "Destek", + "accessibility": "Erişilebilirlik ", + "accessibility-page-enabled": "Erişilebilirlik sayfası etkin", + "accessibility-info-not-added-yet": "Erişilebilirlik bilgisi henüz eklenmedi", + "accessibility-title": "Erişilebilirlik başlığı", + "accessibility-content": "Erişilebilirlik içeriği", + "accounts-lockout-settings": "Kaba Kuvvet Saldırısı Koruması Ayarları", + "accounts-lockout-info": "Bu ayarlar, oturum açma girişimlerinin kaba kuvvet saldırılarına karşı nasıl korunduğunu kontrol eder.", + "accounts-lockout-known-users": "Bilinen kullanıcılar için ayarlar (doğru kullanıcı adı, yanlış parola)", + "accounts-lockout-unknown-users": "Bilinmeyen kullanıcılar için ayarlar (mevcut olmayan kullanıcı adı)", "accounts-lockout-failures-before": "Failures before lockout", "accounts-lockout-period": "Lockout period (seconds)", "accounts-lockout-failure-window": "Failure window (seconds)", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Etkin", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Durum", + "migration-progress-details": "Detaylar", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Tamamlandı", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "ile ilgili", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ug.i18n.json b/imports/i18n/data/ug.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/ug.i18n.json +++ b/imports/i18n/data/ug.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/uk-UA.i18n.json b/imports/i18n/data/uk-UA.i18n.json index 00fbab484..c1c9dac68 100644 --- a/imports/i18n/data/uk-UA.i18n.json +++ b/imports/i18n/data/uk-UA.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "видалено коментар %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Шаблони", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Додати вкладення", @@ -190,7 +202,9 @@ "board-view-collapse": "Згорнути", "board-view-gantt": "Гантт", "board-view-lists": "Списки", - "bucket-example": "Наприклад, 'Список бажань'", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Скасувати", "card-archived": "Цю картку переміщено до архіву.", "board-archived": "Цю дошку переміщено до архіву.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[{\"title\": \"Перший заголовок картки\", \"description\":\"Перший опис картки\"}, {\"title\":\"Другий заголовок картки\",\"description\":\"Другий опис картки\"},{\"title\":\"Останній заголовок картки\",\"description\":\"Останній опис картки\"} ]", "create": "Створити", "createBoardPopup-title": "Створити дошку", + "createTemplateContainerPopup-title": "Додати шаблон контейнера", "chooseBoardSourcePopup-title": "Імпортувати дошку", "createLabelPopup-title": "Створити мітку", "createCustomField": "Створити поле", @@ -354,6 +369,10 @@ "custom-field-text": "Текст", "custom-fields": "Налаштовані поля", "date": "Дата", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Відхилити", "default-avatar": "Аватар за замовчуванням", "delete": "Видалити", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Редагувати сповіщення", "editProfilePopup-title": "Редагувати профіль", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Акаунт створений для вас на __siteName__", "email-enrollAccount-text": "Привіт __user__,\n\nЩоб почати користуватися сервісом, просто натисніть на посилання нижче.\n\n__url__\n\nДякуємо.", "email-fail": "Невдача при відправленні email", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Усі списки, картки, мітки та діяльність будуть видалені, і ви не зможете відновити вміст дошки. Немає відкату.", "boardDeletePopup-title": "Видалити дошку?", "delete-board": "Видалити дошку", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Підзадачі для дошки __board__", "default": "За замовчуванням", "defaultdefault": "За замовчуванням", @@ -755,7 +777,7 @@ "subtask-settings": "Налаштування підзадач", "card-settings": "Налаштування картки", "minicard-settings": "Налаштування міні-картки", - "boardSubtaskSettingsPopup-title": "Налаштування підзадач дошки", + "boardSubtaskSettingsPopup-title": "Налаштування підзадач", "boardCardSettingsPopup-title": "Налаштування картки", "boardMinicardSettingsPopup-title": "Налаштування міні-картки", "deposit-subtasks-board": "Перенести підзадачі на цю дошку:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Я", "dueCardsViewChange-choice-all": "Усі Користувачі", "dueCardsViewChange-choice-all-description": "Показує всі незавершені картки з датою Термін з дошок, для яких користувач має дозвіл.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Пошкоджені Картки", "board-title-not-found": "Дошку '%s' не знайдено.", "swimlane-title-not-found": "Лінію '%s' не знайдено.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Статус", + "migration-progress-details": "Деталі", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "завершено", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "з", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/uk.i18n.json b/imports/i18n/data/uk.i18n.json index 2ce99720e..03e0ac75a 100644 --- a/imports/i18n/data/uk.i18n.json +++ b/imports/i18n/data/uk.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "видалено коментар %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Шаблони", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Додати вкладення", @@ -190,7 +202,9 @@ "board-view-collapse": "Згорнути", "board-view-gantt": "Гантт", "board-view-lists": "Списки", - "bucket-example": "Наприклад, 'Список бажань'", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Скасувати", "card-archived": "Цю картку переміщено до архіву.", "board-archived": "Цю дошку переміщено до архіву.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[{\"title\": \"Перший заголовок картки\", \"description\":\"Перший опис картки\"}, {\"title\":\"Другий заголовок картки\",\"description\":\"Другий опис картки\"},{\"title\":\"Останній заголовок картки\",\"description\":\"Останній опис картки\"} ]", "create": "Створити", "createBoardPopup-title": "Створити дошку", + "createTemplateContainerPopup-title": "Додати шаблон контейнера", "chooseBoardSourcePopup-title": "Імпортувати дошку", "createLabelPopup-title": "Створити мітку", "createCustomField": "Створити поле", @@ -354,6 +369,10 @@ "custom-field-text": "Текст", "custom-fields": "Налаштовані поля", "date": "Дата", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Відхилити", "default-avatar": "Аватар за замовчуванням", "delete": "Видалити", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Редагувати сповіщення", "editProfilePopup-title": "Редагувати профіль", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Акаунт створений для вас на __siteName__", "email-enrollAccount-text": "Привіт __user__,\n\nЩоб почати користуватися сервісом, просто натисніть на посилання нижче.\n\n__url__\n\nДякуємо.", "email-fail": "Невдача при відправленні email", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "Усі списки, картки, мітки та діяльність будуть видалені, і ви не зможете відновити вміст дошки. Немає відкату.", "boardDeletePopup-title": "Видалити дошку?", "delete-board": "Видалити дошку", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Підзадачі для дошки __board__", "default": "За замовчуванням", "defaultdefault": "За замовчуванням", @@ -755,7 +777,7 @@ "subtask-settings": "Налаштування підзадач", "card-settings": "Налаштування картки", "minicard-settings": "Налаштування міні-картки", - "boardSubtaskSettingsPopup-title": "Налаштування підзадач дошки", + "boardSubtaskSettingsPopup-title": "Налаштування підзадач", "boardCardSettingsPopup-title": "Налаштування картки", "boardMinicardSettingsPopup-title": "Налаштування міні-картки", "deposit-subtasks-board": "Перенести підзадачі на цю дошку:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Я", "dueCardsViewChange-choice-all": "Усі Користувачі", "dueCardsViewChange-choice-all-description": "Показує всі незавершені картки з датою Термін з дошок, для яких користувач має дозвіл.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Пошкоджені Картки", "board-title-not-found": "Дошку '%s' не знайдено.", "swimlane-title-not-found": "Лінію '%s' не знайдено.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Статус", + "migration-progress-details": "Деталі", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "завершено", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "з", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/uz-AR.i18n.json b/imports/i18n/data/uz-AR.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/uz-AR.i18n.json +++ b/imports/i18n/data/uz-AR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/uz-LA.i18n.json b/imports/i18n/data/uz-LA.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/uz-LA.i18n.json +++ b/imports/i18n/data/uz-LA.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/uz-UZ.i18n.json b/imports/i18n/data/uz-UZ.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/uz-UZ.i18n.json +++ b/imports/i18n/data/uz-UZ.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/uz.i18n.json b/imports/i18n/data/uz.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/uz.i18n.json +++ b/imports/i18n/data/uz.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ve-CC.i18n.json b/imports/i18n/data/ve-CC.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/ve-CC.i18n.json +++ b/imports/i18n/data/ve-CC.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ve-PP.i18n.json b/imports/i18n/data/ve-PP.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/ve-PP.i18n.json +++ b/imports/i18n/data/ve-PP.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/ve.i18n.json b/imports/i18n/data/ve.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/ve.i18n.json +++ b/imports/i18n/data/ve.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/vi-VN.i18n.json b/imports/i18n/data/vi-VN.i18n.json index 1d3af35b5..feb1c09e8 100644 --- a/imports/i18n/data/vi-VN.i18n.json +++ b/imports/i18n/data/vi-VN.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/vi.i18n.json b/imports/i18n/data/vi.i18n.json index 2e96d9dcd..90628f3aa 100644 --- a/imports/i18n/data/vi.i18n.json +++ b/imports/i18n/data/vi.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "đã xoá lời bình %s", "activity-receivedDate": "đã sửa ngày nhận đến %s của %s", "activity-startDate": "đã sửa ngày bắt đầu thành %s của %s", + "allboards.starred": "Starred", + "allboards.templates": "Các mẫu", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "đã sửa ngày hết hạn thành %s của %s", "activity-endDate": "đã sửa ngày kết thúc thành %s của %s", "add-attachment": "Thêm Bản Đính Kèm", @@ -190,7 +202,9 @@ "board-view-collapse": "Thu gọn", "board-view-gantt": "Biểu đồ Gantt", "board-view-lists": "Danh sách", - "bucket-example": "Ví dụ như \"Danh sách nhóm\"", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Hủy", "card-archived": "Thẻ này đã được chuyển đến Lưu trữ.", "board-archived": "Bảng này đã được chuyển đến Lưu trữ.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"Tiêu đề thẻ đầu tiên\", \"description\":\"Mô tả thẻ đầu tiên\"}, {\"title\":\"Tiêu đề thẻ thứ hai\",\"description\":\"Mô tả thẻ thứ hai\"},{\"title\":\"Tiêu đề thẻ cuối cùng\",\"description\":\"Mô tả thẻ cuối cùng\"} ]", "create": "Tạo", "createBoardPopup-title": "Tạo Bảng", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Nhập bảng", "createLabelPopup-title": "Tạo nhãn", "createCustomField": "Tạo Trường", @@ -354,6 +369,10 @@ "custom-field-text": "Văn bản", "custom-fields": "Trường tùy chỉnh", "date": "Ngày", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Từ chối", "default-avatar": "Hình đại diện mặc định", "delete": "Xoá", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Sửa Thông báo", "editProfilePopup-title": "Sửa Hồ sơ", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "Một tài khoản được tạo cho bạn trên __siteName__", "email-enrollAccount-text": "Chào __user__,\n\nĐể bắt đầu sử dụng dịch vụ, chỉ cần nhấp vào liên kết bên dưới.\n\n__url__\n\nCảm ơn.", "email-fail": "Gửi email không thành công", @@ -748,6 +768,8 @@ "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?", "delete-board": "Xoá Bảng", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Nhiệm vụ phụ cho __board__ bảng", "default": "Mặc định", "defaultdefault": "Mặc định", @@ -755,7 +777,7 @@ "subtask-settings": "Cài đặt Nhiệm vụ phụ", "card-settings": "Cài đặt Thẻ", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Cài đặt Bảng Nhiệm vụ phụ", + "boardSubtaskSettingsPopup-title": "Cài đặt Nhiệm vụ phụ", "boardCardSettingsPopup-title": "Cài đặt Thẻ", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Gửi các nhiệm vụ phụ vào bảng này:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Tôi", "dueCardsViewChange-choice-all": "Tất cả người dùng", "dueCardsViewChange-choice-all-description": "Hiển thị tất cả các thẻ chưa hoàn thành có ngày *Đến hạn* từ bảng mà người dùng có quyền.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Thẻ bị hỏng", "board-title-not-found": "Không tìm thấy bảng '%s'", "swimlane-title-not-found": "Không tìm thấy làn ngang '%s'", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Trạng thái", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Đã hoàn thành", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "của", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/vl-SS.i18n.json b/imports/i18n/data/vl-SS.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/vl-SS.i18n.json +++ b/imports/i18n/data/vl-SS.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/vo.i18n.json b/imports/i18n/data/vo.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/vo.i18n.json +++ b/imports/i18n/data/vo.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/wa-RR.i18n.json b/imports/i18n/data/wa-RR.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/wa-RR.i18n.json +++ b/imports/i18n/data/wa-RR.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/wa.i18n.json b/imports/i18n/data/wa.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/wa.i18n.json +++ b/imports/i18n/data/wa.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/wo.i18n.json b/imports/i18n/data/wo.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/wo.i18n.json +++ b/imports/i18n/data/wo.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/wuu-Hans.i18n.json b/imports/i18n/data/wuu-Hans.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/wuu-Hans.i18n.json +++ b/imports/i18n/data/wuu-Hans.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/xh.i18n.json b/imports/i18n/data/xh.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/xh.i18n.json +++ b/imports/i18n/data/xh.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/yi.i18n.json b/imports/i18n/data/yi.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/yi.i18n.json +++ b/imports/i18n/data/yi.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/yo.i18n.json b/imports/i18n/data/yo.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/yo.i18n.json +++ b/imports/i18n/data/yo.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/yue_CN.i18n.json b/imports/i18n/data/yue_CN.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/yue_CN.i18n.json +++ b/imports/i18n/data/yue_CN.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/zgh.i18n.json b/imports/i18n/data/zgh.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/zgh.i18n.json +++ b/imports/i18n/data/zgh.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/zh-CN.i18n.json b/imports/i18n/data/zh-CN.i18n.json index 237e5cfbb..517728311 100644 --- a/imports/i18n/data/zh-CN.i18n.json +++ b/imports/i18n/data/zh-CN.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "评论已删除", "activity-receivedDate": "已将接收日期从 %s 修改为 %s", "activity-startDate": "已将开始日期从 %s 修改为 %s", + "allboards.starred": "Starred", + "allboards.templates": "模板", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "已将到期日期从 %s 修改为 %s", "activity-endDate": "已将结束日期从 %s 修改为 %s", "add-attachment": "添加附件", @@ -190,7 +202,9 @@ "board-view-collapse": "崩溃", "board-view-gantt": "甘特图", "board-view-lists": "列表", - "bucket-example": "例:Bucket List", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "取消", "card-archived": "归档这个卡片。", "board-archived": "归档这个看板。", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"第一个卡片的标题\", \"description\":\"第一个卡片的描述\"}, {\"title\":\"第二个卡片的标题\",\"description\":\"第二个卡片的描述\"},{\"title\":\"最后一个卡片的标题\",\"description\":\"最后一个卡片的描述\"} ]", "create": "创建", "createBoardPopup-title": "创建看板", + "createTemplateContainerPopup-title": "新增模板容器", "chooseBoardSourcePopup-title": "导入看板", "createLabelPopup-title": "创建标签", "createCustomField": "创建字段", @@ -354,6 +369,10 @@ "custom-field-text": "文本", "custom-fields": "自定义字段", "date": "日期", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "拒绝", "default-avatar": "默认头像", "delete": "删除", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "编辑通知", "editProfilePopup-title": "编辑资料", "email": "邮箱", + "email-address": "Email Address", "email-enrollAccount-subject": "已为您在 __siteName__ 创建帐号", "email-enrollAccount-text": "尊敬的 __user__,\n\n点击下面的链接,即刻开始使用这项服务。\n\n__url__\n\n谢谢。", "email-fail": "邮件发送失败", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "所有列表、卡片、标签和活动都回被删除,将无法恢复看板内容。不支持撤销。", "boardDeletePopup-title": "删除看板?", "delete-board": "删除看板", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "__board__ 看板的子任务", "default": "默认", "defaultdefault": "默认", @@ -755,7 +777,7 @@ "subtask-settings": "子任务设置", "card-settings": "卡片设置", "minicard-settings": "小卡片设置", - "boardSubtaskSettingsPopup-title": "看板子任务设置", + "boardSubtaskSettingsPopup-title": "子任务设置", "boardCardSettingsPopup-title": "卡片设置", "boardMinicardSettingsPopup-title": "小卡片设置", "deposit-subtasks-board": "将子任务放入以下看板:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "我", "dueCardsViewChange-choice-all": "所有用户", "dueCardsViewChange-choice-all-description": "根据截至日期显示用户有权限访问的看板中未完成的卡片。", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "损坏的卡片", "board-title-not-found": "无法找到看板 '%s'", "swimlane-title-not-found": "找不到泳道 %s", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "完成", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "状态", + "migration-progress-details": "详情", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "已完成", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "分之", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "权重", + "idle": "空闲", + "complete": "完成", + "cron": "定时任务" } diff --git a/imports/i18n/data/zh-GB.i18n.json b/imports/i18n/data/zh-GB.i18n.json index fbaf5caec..e75ee1b35 100644 --- a/imports/i18n/data/zh-GB.i18n.json +++ b/imports/i18n/data/zh-GB.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/zh-HK.i18n.json b/imports/i18n/data/zh-HK.i18n.json index a43aa4e5d..b5506b271 100644 --- a/imports/i18n/data/zh-HK.i18n.json +++ b/imports/i18n/data/zh-HK.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/zh-Hans.i18n.json b/imports/i18n/data/zh-Hans.i18n.json index a3a177ba3..76f2b352c 100644 --- a/imports/i18n/data/zh-Hans.i18n.json +++ b/imports/i18n/data/zh-Hans.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "创建", "createBoardPopup-title": "创建看板", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "导入看板", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "文本", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "删除", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/zh-Hant.i18n.json b/imports/i18n/data/zh-Hant.i18n.json index 87918c182..28b61bb3b 100644 --- a/imports/i18n/data/zh-Hant.i18n.json +++ b/imports/i18n/data/zh-Hant.i18n.json @@ -1,6 +1,6 @@ { - "accept": "Accept", - "act-activity-notify": "Activity Notification", + "accept": "接受", + "act-activity-notify": "動態通知", "act-addAttachment": "added attachment __attachment__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", "act-deleteAttachment": "deleted attachment __attachment__ at card __card__ at list __list__ at swimlane __swimlane__ at board __board__", "act-addSubtask": "added subtask __subtask__ to card __card__ at list __list__ at swimlane __swimlane__ at board __board__", @@ -48,7 +48,7 @@ "activity-added": "added %s to %s", "activity-archived": "%s moved to Archive", "activity-attached": "attached %s to %s", - "activity-created": "created %s", + "activity-created": "已建立", "activity-changedListTitle": "renamed list to %s", "activity-customfield-created": "created custom field %s", "activity-excluded": "excluded %s from %s", @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/zh-TW.i18n.json b/imports/i18n/data/zh-TW.i18n.json index 4e19be763..302092c7c 100644 --- a/imports/i18n/data/zh-TW.i18n.json +++ b/imports/i18n/data/zh-TW.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "評論已刪除", "activity-receivedDate": "已編輯收到日期為 %s %s", "activity-startDate": "已編輯起始日期為 %s %s", + "allboards.starred": "已加星號", + "allboards.templates": "範本", + "allboards.remaining": "剩餘", + "allboards.workspaces": "工作空間", + "allboards.add-workspace": "新增工作空間", + "allboards.add-workspace-prompt": "工作空間名稱", + "allboards.add-subworkspace": "新增子工作空間", + "allboards.add-subworkspace-prompt": "子工作空間名稱", + "allboards.edit-workspace": "編輯工作空間", + "allboards.edit-workspace-name": "工作空間名稱", + "allboards.edit-workspace-icon": "工作空間圖示 (markdown)", + "multi-selection-active": "點選核取方塊以選取看板", "activity-dueDate": "已編輯截止日期為 %s %s", "activity-endDate": "已編輯結束日期為 %s %s", "add-attachment": "新增附件", @@ -177,20 +189,22 @@ "boardChangeViewPopup-title": "看板檢視", "boards": "看板", "board-view": "看板檢視", - "desktop-mode": "Desktop Mode", - "mobile-mode": "Mobile Mode", - "mobile-desktop-toggle": "Toggle between Mobile and Desktop Mode", - "zoom-in": "Zoom In", - "zoom-out": "Zoom Out", - "click-to-change-zoom": "Click to change zoom level", - "zoom-level": "Zoom Level", - "enter-zoom-level": "Enter zoom level (50-300%):", + "desktop-mode": "桌面模式", + "mobile-mode": "行動裝置模式", + "mobile-desktop-toggle": "在行動裝置與桌面模式間切換", + "zoom-in": "放大", + "zoom-out": "縮小", + "click-to-change-zoom": "點選以變更縮放層級", + "zoom-level": "縮放層級", + "enter-zoom-level": "輸入縮放層級 (50-300%):", "board-view-cal": "日曆", "board-view-swimlanes": "泳道", - "board-view-collapse": "損毀", + "board-view-collapse": "折疊", "board-view-gantt": "甘特圖", "board-view-lists": "清單", - "bucket-example": "例如「目標清單」", + "bucket-example": "例如「人生清單」", + "calendar-previous-month-label": "上個月", + "calendar-next-month-label": "下個月", "cancel": "取消", "card-archived": "封存這個卡片。", "board-archived": "封存這個看板。", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"第一個卡片標題\", \"description\":\"第一個卡片描述\"}, {\"title\":\"第二個卡片標題\",\"description\":\"第二個卡片描述\"},{\"title\":\"最後一個卡片標題\",\"description\":\"最後一個卡片描述\"} ]", "create": "建立", "createBoardPopup-title": "建立看板", + "createTemplateContainerPopup-title": "新增範本容器", "chooseBoardSourcePopup-title": "匯入看板", "createLabelPopup-title": "新增標籤", "createCustomField": "建立欄位", @@ -354,6 +369,10 @@ "custom-field-text": "文字", "custom-fields": "自訂欄位", "date": "日期", + "date-format": "日期格式", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "拒絕", "default-avatar": "預設大頭照", "delete": "刪除", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "更改通知", "editProfilePopup-title": "編輯個人資料", "email": "電子郵件", + "email-address": "電子郵件地址", "email-enrollAccount-subject": "您在 __siteName__ 的帳號已經建立", "email-enrollAccount-text": "親愛的 __user__,\n\n點選下面的連結,即刻開始使用這項服務。\n\n__url__\n\n謝謝。", "email-fail": "郵件寄送失敗", @@ -446,8 +466,8 @@ "filter-no-label": "沒有標籤", "filter-member-label": "按成員篩選", "filter-no-member": "沒有成員", - "filter-assignee-label": "按代理人篩選", - "filter-no-assignee": "沒有代理人", + "filter-assignee-label": "按承辦人篩選", + "filter-no-assignee": "沒有承辦人", "filter-custom-fields-label": "按自訂欄位篩選", "filter-no-custom-fields": "沒有自訂欄位", "filter-show-archive": "顯示封存的清單", @@ -619,7 +639,7 @@ "has-spenttime-cards": "耗時卡", "time": "時間", "title": "標題", - "toggle-assignees": "切換卡片的代理人 1-9(按加入看板的順序)。", + "toggle-assignees": "切換卡片的承辦人 1-9(按加入看板的順序)。", "toggle-labels": "切換卡片的標籤 1-9。多重選擇新增標籤 1-9", "remove-labels-multiselect": "多重選擇移除標籤 1-9", "tracking": "訂閱相關通知", @@ -631,9 +651,9 @@ "upload": "上傳", "upload-avatar": "上傳大頭照", "uploaded-avatar": "大頭照已經上傳", - "uploading-files": "Uploading files", - "upload-failed": "Upload failed", - "upload-completed": "Upload completed", + "uploading-files": "正在上傳檔案", + "upload-failed": "上傳失敗", + "upload-completed": "上傳完成", "custom-top-left-corner-logo-image-url": "自訂左上商標圖示網址", "custom-top-left-corner-logo-link-url": "自訂左上商標連結網址", "custom-top-left-corner-logo-height": "自訂左上商標圖示高度。預設值:27", @@ -748,6 +768,8 @@ "delete-board-confirm-popup": "所有清單、卡片、標籤和活動都會被刪除,將無法恢覆看板內容。不支援撤銷。", "boardDeletePopup-title": "刪除看板?", "delete-board": "刪除看板", + "delete-duplicate-lists": "刪除重複的清單", + "delete-duplicate-lists-confirm": "您確定嗎?這將會刪除所有相同名稱但不包含卡片的重複清單。", "default-subtasks-board": "__board__ 看板的子任務", "default": "預設值", "defaultdefault": "預設值", @@ -755,7 +777,7 @@ "subtask-settings": "子任務設定", "card-settings": "卡片設定", "minicard-settings": "小卡片設定", - "boardSubtaskSettingsPopup-title": "看板子任務設定", + "boardSubtaskSettingsPopup-title": "子任務設定", "boardCardSettingsPopup-title": "卡片設定", "boardMinicardSettingsPopup-title": "小卡片設定", "deposit-subtasks-board": "將子任務放入以下看板:", @@ -941,8 +963,8 @@ "accounts-allowUserDelete": "允許用戶自行刪除其帳戶", "hide-minicard-label-text": "隱藏迷你卡片標籤內文", "show-desktop-drag-handles": "顯示桌面拖曳工具", - "assignee": "代理人", - "cardAssigneesPopup-title": "代理人", + "assignee": "承辦人", + "cardAssigneesPopup-title": "承辦人", "addmore-detail": "新增更多詳細描述", "show-on-card": "在卡片上顯示", "show-on-minicard": "在小卡片顯示", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "我", "dueCardsViewChange-choice-all": "全部使用者", "dueCardsViewChange-choice-all-description": "顯示看板內所有已設定到期日,且使用者有權限的未完成卡片", + "dueCards-noResults-title": "找不到到期卡片", + "dueCards-noResults-description": "您目前沒有任何有到期日的卡片。", "broken-cards": "損毀卡片", "board-title-not-found": "看板%s不存在", "swimlane-title-not-found": "泳道流程圖%s不存在", @@ -1036,7 +1060,7 @@ "operator-user-abbrev": "@", "operator-member": "成員", "operator-member-abbrev": "m", - "operator-assignee": "代理人", + "operator-assignee": "承辦人", "operator-assignee-abbrev": "a", "operator-creator": "建立者", "operator-status": "狀態", @@ -1067,7 +1091,7 @@ "predicate-checklist": "待辦清單", "predicate-start": "開始", "predicate-end": "完成", - "predicate-assignee": "代理人", + "predicate-assignee": "承辦人", "predicate-member": "成員", "predicate-public": "公開", "predicate-private": "私有", @@ -1092,10 +1116,10 @@ "globalSearch-instructions-operator-comment": "`__operator_comment__:` - 卡片評論包含 **.", "globalSearch-instructions-operator-label": "`__operator_label__:` `__operator_label__:` - 卡片標籤要符合 ** 或 *", "globalSearch-instructions-operator-hash": "`__operator_label_abbrev__` - 的簡寫 `__operator_label__:` 或 `__operator_label__:`", - "globalSearch-instructions-operator-user": "`__operator_user__:` - 卡片,其中 ** 是 *成員* 或 *代理人*", + "globalSearch-instructions-operator-user": "`__operator_user__:` - 卡片,其中 ** 是 *成員* 或 *承辦人*", "globalSearch-instructions-operator-at": "`__operator_user_abbrev__username` - `user:` 的簡寫", "globalSearch-instructions-operator-member": "`__operator_member__:` - 卡片,其中 ** 是i *成員*", - "globalSearch-instructions-operator-assignee": "`__operator_assignee__:` - 卡片,其中 ** 是 *代理人*", + "globalSearch-instructions-operator-assignee": "`__operator_assignee__:` - 卡片,其中 ** 是 *承辦人*", "globalSearch-instructions-operator-creator": "`__operator_creator__:` - 卡片,其中 ** 是卡片的建立者", "globalSearch-instructions-operator-org": "`__operator_org__:` - 屬於分配給組織 ** 看板的卡片", "globalSearch-instructions-operator-team": "`__operator_team__:` - 屬於分配給團隊 ** 看板的卡片", @@ -1273,7 +1297,7 @@ "show-week-of-year": "顯示年度週數 (ISO 8601)", "convert-to-markdown": "轉換為 Markdown", "import-board-zip": "新增包含看板 JSON 檔案與帶有附件的看板名稱子目錄的 .zip 檔案", - "collapse": "損毀", + "collapse": "折疊", "uncollapse": "展開", "hideCheckedChecklistItems": "隱藏已勾選的待辦清單項目", "hideAllChecklistItems": "隱藏所有待辦清單項目", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "使用者活躍 -點選以停用", "admin-people-user-inactive": "使用者不活躍 - 點選以啟用", "accounts-lockout-all-users-unlocked": "所有鎖定的使用者均已解鎖", - "accounts-lockout-unlock-all": "解鎖全部" + "accounts-lockout-unlock-all": "解鎖全部", + "active-cron-jobs": "作用中的排程工作", + "add-cron-job": "新增排程工作", + "add-cron-job-placeholder": "新增排程工作的功能即將推出", + "attachment-storage-configuration": "附件儲存空間組態", + "attachments-path": "附件路徑", + "attachments-path-description": "附件檔案儲存路徑", + "avatars-path": "大頭照路徑", + "avatars-path-description": "大頭照檔案儲存的路徑", + "board-archive-failed": "安排看板封存失敗", + "board-archive-scheduled": "安排看板封存成功", + "board-backup-failed": "安排看板備份失敗", + "board-backup-scheduled": "安排看板備份成功", + "board-cleanup-failed": "安排看板清理失敗", + "board-cleanup-scheduled": "安排看板清理成功", + "board-operations": "看板操作", + "cron-jobs": "排程工作", + "cron-migrations": "排程遷移", + "cron-job-delete-confirm": "您確定您想要刪除此排程工作嗎?", + "cron-job-delete-failed": "刪除排程工作失敗", + "cron-job-deleted": "排程工作刪除成功", + "cron-job-pause-failed": "暫停排程工作失敗", + "cron-job-paused": "排程工作暫停失敗", + "filesystem-path-description": "檔案儲存空間的基礎路徑", + "gridfs-enabled": "已啟用 GridFS", + "gridfs-enabled-description": "使用 MongoDB GridFS 作為檔案儲存空間", + "migration-pause-failed": "暫停遷移失敗", + "migration-paused": "暫停遷移成功", + "migration-progress": "遷移進度", + "migration-start-failed": "開始遷移失敗", + "migration-started": "開始遷移成功", + "migration-status": "遷移狀態", + "migration-stop-confirm": "您確定您想要停止所有遷移嗎?", + "migration-stop-failed": "停止遷移失敗", + "migration-stopped": "停止遷移成功", + "mongodb-gridfs-storage": "MongoDB GridFS 儲存空間", + "pause-all-migrations": "暫停所有遷移", + "s3-access-key": "S3 存取金鑰", + "s3-access-key-description": "用於驗證的 AWS S3 存取金鑰", + "s3-access-key-placeholder": "輸入 S3 存取金鑰", + "s3-bucket": "S3 儲存桶", + "s3-bucket-description": "儲存檔案用的 S3 儲存桶名稱", + "s3-connection-failed": "S3 連線失敗", + "s3-connection-success": "S3 連線成功", + "s3-enabled": "已啟用 S3", + "s3-enabled-description": "使用 AWS S3 或 MinIO 作為檔案儲存空間", + "s3-endpoint": "S3 端點", + "s3-endpoint-description": "S3 端點 URL(例如 s3.amazonaws.com 或 minio.example.com)", + "s3-minio-storage": "S3/MinIO 儲存空間", + "s3-port": "S3 連接埠", + "s3-port-description": "S3 端點連接埠號", + "s3-region": "S3 區域", + "s3-region-description": "AWS S3 區域(例如 us-east-1)", + "s3-secret-key": "S3 祕密金鑰", + "s3-secret-key-description": "用於驗證的 AWS S3 祕密金鑰", + "s3-secret-key-placeholder": "輸入 S3 祕密金鑰", + "s3-secret-key-required": "S3 祕密金鑰必填", + "s3-settings-save-failed": "儲存 S3 設定失敗", + "s3-settings-saved": "S3 設定儲存成功", + "s3-ssl-enabled": "已啟用 S3 SSL", + "s3-ssl-enabled-description": "為 S3 連線使用 SSL/TLS", + "save-s3-settings": "儲存 S3 設定", + "schedule-board-archive": "安排看板封存", + "schedule-board-backup": "安排看板備份", + "schedule-board-cleanup": "安排看板清理", + "scheduled-board-operations": "排程看板操作", + "start-all-migrations": "開始所有遷移", + "stop-all-migrations": "停止所有遷移", + "test-s3-connection": "測試 S3 連線", + "writable-path": "可寫路徑", + "writable-path-description": "檔案儲存空間的基礎目錄路徑", + "add-job": "新增工作", + "attachment-migration": "附件遷移", + "attachment-monitoring": "附件監控", + "attachment-settings": "附件設定", + "attachment-storage-settings": "儲存空間設定", + "automatic-migration": "自動遷移", + "back-to-settings": "回到設定", + "board-id": "看板 ID", + "board-migration": "看板遷移", + "board-migrations": "看板遷移", + "card-show-lists-on-minicard": "在迷你卡片上顯示清單", + "comprehensive-board-migration": "全面看板遷移", + "comprehensive-board-migration-description": "執行全面檢查與修復,確保看板資料完整性,包括清單排序、卡片位置及泳道結構。", + "delete-duplicate-empty-lists-migration": "刪除重複的空清單", + "delete-duplicate-empty-lists-migration-description": "安全地刪除空的重複清單。僅移除既無卡片、又存在標題相同且含卡片的另一份清單的清單。", + "lost-cards": "遺失的卡片", + "lost-cards-list": "已還原的項目", + "restore-lost-cards-migration": "還原遺失的卡片", + "restore-lost-cards-migration-description": "尋找並還原缺少泳道 ID 或清單 ID 的卡片與清單。建立「遺失的卡片」泳道,使所有遺失項目重新可見。", + "restore-all-archived-migration": "還原所有封存", + "restore-all-archived-migration-description": "還原所有已封存的泳道、清單與卡片。自動修復任何缺少泳道 ID 或清單 ID 的項目以使它們重新可見。", + "fix-missing-lists-migration": "修復遺失的清單", + "fix-missing-lists-migration-description": "偵測並修復在看板結構中遺失或損毀的清單。", + "fix-avatar-urls-migration": "修復大頭照 URL", + "fix-avatar-urls-migration-description": "更新看板成員的大頭照 URL 以使用正確的儲存空間後端並修復損壞的大頭照參照。", + "fix-all-file-urls-migration": "修復所有檔案 URL", + "fix-all-file-urls-migration-description": "更新所有此看板的檔案附件 URL 以使用正確的儲存空間後端並修復損壞的檔案參照。", + "migration-needed": "需要遷移", + "migration-complete": "完成", + "migration-running": "正在執行……", + "migration-successful": "遷移成功完成", + "migration-failed": "遷移失敗", + "migrations": "遷移", + "migrations-admin-only": "僅看板管理員可執行遷移", + "migrations-description": "為此看板執行資料完整性檢查並修復。每個遷移皆可單獨執行。", + "no-issues-found": "未找到問題", + "run-migration": "執行遷移", + "run-comprehensive-migration-confirm": "這將會執行全面的遷移以檢查並修復看板資料完整性。這可能需要數分鐘。要繼續嗎?", + "run-delete-duplicate-empty-lists-migration-confirm": "此操作將先將所有共享清單轉換為每個泳道專屬的清單,接著刪除那些存在標題相同且含卡片之重複清單的空清單。僅會移除真正冗餘的空清單。要繼續嗎?", + "run-restore-lost-cards-migration-confirm": "這將建立一個「遺失的卡片」泳道,並還原所有缺少泳道 ID 或清單 ID 的卡片與清單。此操作僅影響未封存項目。繼續?", + "run-restore-all-archived-migration-confirm": "此操作將還原所有已封存的泳道、清單及卡片,使其重新顯示。任何缺少 ID 的項目將自動修復。此操作無法輕易撤銷。要繼續嗎?", + "run-fix-missing-lists-migration-confirm": "這將會偵測並修復在看板結構中遺失或損毀的清單。要繼續嗎?", + "run-fix-avatar-urls-migration-confirm": "這將會更新看板成員的大頭照 URL 以使用正確的儲存空間後端。要繼續嗎?", + "run-fix-all-file-urls-migration-confirm": "這將會更新此看板上的所有檔案附件 URL 以使用正確的儲存空間後端。要繼續嗎?", + "restore-lost-cards-nothing-to-restore": "沒有需要還原的遺失泳道、清單或卡片", + + "migration-progress-title": "正在進行看板遷移", + "migration-progress-overall": "整體進度", + "migration-progress-current-step": "目前步驟", + "migration-progress-status": "狀態", + "migration-progress-details": "內容", + "migration-progress-note": "請稍候,我們正在將您的看板遷移至最新結構……", + + "step-analyze-board-structure": "分析看板結構", + "step-fix-orphaned-cards": "修復孤立卡片", + "step-convert-shared-lists": "轉換共享清單", + "step-ensure-per-swimlane-lists": "確保每個泳道專屬的清單", + "step-validate-migration": "驗證遷移", + "step-fix-avatar-urls": "修復大頭照 URL", + "step-fix-attachment-urls": "修復附件 URL", + "step-analyze-lists": "分析清單", + "step-create-missing-lists": "建立遺失的清單", + "step-update-cards": "更新卡片", + "step-finalize": "完成", + "step-delete-duplicate-empty-lists": "刪除重複的空清單", + "step-ensure-lost-cards-swimlane": "確保遺失的卡片泳道", + "step-restore-lists": "還原清單", + "step-restore-cards": "還原卡片", + "step-restore-swimlanes": "還原泳道", + "step-fix-missing-ids": "修復遺失的 ID", + "step-scan-users": "正在檢查看板成員大頭照", + "step-scan-files": "正在檢查看板檔案附件", + "step-fix-file-urls": "正在修復檔案 URL", + "cleanup": "清理", + "cleanup-old-jobs": "清理舊工作", + "completed": "已完成", + "conversion-info-text": "此轉換操作每個看板僅執行一次,可提升效能表現。您可繼續正常使用該看板。", + "converting-board": "正在轉換看板", + "converting-board-description": "轉換看板結構以提升功能性。此過程可能需要一點時間。", + "cpu-cores": "CPU 核心數", + "cpu-usage": "CPU 使用率", + "current-action": "目前動作", + "database-migration": "資料庫遷移", + "database-migration-description": "轉換資料庫結構以提升功能性與效能。此過程可能需要數分鐘。", + "database-migrations": "資料庫遷移", + "days-old": "天", + "duration": "持續時間", + "errors": "錯誤", + "estimated-time-remaining": "預估剩餘時間", + "every-1-day": "每 1 天", + "every-1-hour": "每 1 小時", + "every-1-minute": "每 1 分鐘", + "every-10-minutes": "每 10 分鐘", + "every-30-minutes": "每 30 分鐘", + "every-5-minutes": "每 5 分鐘", + "every-6-hours": "每 6 小時", + "export-monitoring": "匯出監控", + "filesystem-attachments": "檔案系統附件", + "filesystem-size": "檔案系統大小", + "filesystem-storage": "檔案系統儲存空間", + "force-board-scan": "強制看板掃描", + "gridfs-attachments": "GridFS 附件", + "gridfs-size": "GridFS 大小", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "在迷你卡片上隱藏清單", + "idle-migration": "閒置遷移", + "job-description": "工作描述", + "job-details": "工作詳細資訊", + "job-name": "工作名稱", + "job-queue": "工作佇列", + "last-run": "上次執行", + "max-concurrent": "最大並行數", + "memory-usage": "記憶體使用率", + "migrate-all-to-filesystem": "遷移全部到檔案系統", + "migrate-all-to-gridfs": "遷移全部到 GridFS", + "migrate-all-to-s3": "遷移全部到 S3", + "migrated-attachments": "已遷移的附件", + "migration-batch-size": "批次大小", + "migration-batch-size-description": "每批次處理的附件數量 (1-100)", + "migration-cpu-threshold": "CPU 閾值 (%)", + "migration-cpu-threshold-description": "當 CPU 使用率超過此百分比時暫停遷移 (10-90)", + "migration-delay-ms": "延遲(毫秒)", + "migration-delay-ms-description": "批次間延遲時間 (100-10000)(單位為毫秒)", + "migration-detector": "遷移偵測器", + "migration-info-text": "資料庫遷移僅執行一次,可提升系統效能。即使關閉瀏覽器,此過程仍會在背景持續進行。", + "migration-log": "遷移紀錄檔", + "migration-markers": "遷移標記", + "migration-resume-failed": "繼續遷移失敗", + "migration-resumed": "繼續遷移", + "migration-steps": "遷移步驟", + "migration-warning-text": "請勿在遷移過程中關閉瀏覽器。該過程將在背景持續執行,但可能需要較長時間才能完成。", + "monitoring-export-failed": "匯出監控資料失敗", + "monitoring-refresh-failed": "重新整理監控資料失敗", + "next": "下一個", + "next-run": "下次執行", + "of": "的", + "operation-type": "操作類型", + "overall-progress": "整體進度", + "page": "頁面", + "pause-migration": "暫停遷移", + "previous": "前一個", + "refresh": "重新整理", + "refresh-monitoring": "重新整理監控", + "remaining-attachments": "剩餘附件", + "resume-migration": "繼續遷移", + "run-once": "執行一次", + "s3-attachments": "S3 附件", + "s3-size": "S3 大小", + "s3-storage": "S3", + "scanning-status": "掃描狀態", + "schedule": "排程", + "search-boards-or-operations": "搜尋看板或操作……", + "show-list-on-minicard": "在迷你卡片顯示清單", + "showing": "顯示", + "start-test-operation": "開始測試操作", + "start-time": "開始時間", + "step-progress": "步驟進度", + "stop-migration": "停止遷移", + "storage-distribution": "儲存空間散佈", + "system-resources": "系統資源", + "total-attachments": "附件總數", + "total-operations": "操作總數", + "total-size": "總大小", + "unmigrated-boards": "尚未遷移的看板", + "weight": "權重", + "idle": "閒置", + "complete": "完成", + "cron": "Cron" } diff --git a/imports/i18n/data/zh.i18n.json b/imports/i18n/data/zh.i18n.json index eb05db9d8..e7bfa720a 100644 --- a/imports/i18n/data/zh.i18n.json +++ b/imports/i18n/data/zh.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/zu-ZA.i18n.json b/imports/i18n/data/zu-ZA.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/zu-ZA.i18n.json +++ b/imports/i18n/data/zu-ZA.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/data/zu.i18n.json b/imports/i18n/data/zu.i18n.json index 87918c182..acf3c6934 100644 --- a/imports/i18n/data/zu.i18n.json +++ b/imports/i18n/data/zu.i18n.json @@ -78,6 +78,18 @@ "activity-deleteComment": "deleted comment %s", "activity-receivedDate": "edited received date to %s of %s", "activity-startDate": "edited start date to %s of %s", + "allboards.starred": "Starred", + "allboards.templates": "Templates", + "allboards.remaining": "Remaining", + "allboards.workspaces": "Workspaces", + "allboards.add-workspace": "Add Workspace", + "allboards.add-workspace-prompt": "Workspace name", + "allboards.add-subworkspace": "Add Subworkspace", + "allboards.add-subworkspace-prompt": "Subworkspace name", + "allboards.edit-workspace": "Edit workspace", + "allboards.edit-workspace-name": "Workspace name", + "allboards.edit-workspace-icon": "Workspace icon (markdown)", + "multi-selection-active": "Click checkboxes to select boards", "activity-dueDate": "edited due date to %s of %s", "activity-endDate": "edited end date to %s of %s", "add-attachment": "Add Attachment", @@ -190,7 +202,9 @@ "board-view-collapse": "Collapse", "board-view-gantt": "Gantt", "board-view-lists": "Lists", - "bucket-example": "Like “Bucket List” for example", + "bucket-example": "Like \"Bucket List\" for example", + "calendar-previous-month-label": "Previous Month", + "calendar-next-month-label": "Next Month", "cancel": "Cancel", "card-archived": "This card is moved to Archive.", "board-archived": "This board is moved to Archive.", @@ -335,6 +349,7 @@ "copyManyCardsPopup-format": "[ {\"title\": \"First card title\", \"description\":\"First card description\"}, {\"title\":\"Second card title\",\"description\":\"Second card description\"},{\"title\":\"Last card title\",\"description\":\"Last card description\"} ]", "create": "Create", "createBoardPopup-title": "Create Board", + "createTemplateContainerPopup-title": "Add Template Container", "chooseBoardSourcePopup-title": "Import board", "createLabelPopup-title": "Create Label", "createCustomField": "Create Field", @@ -354,6 +369,10 @@ "custom-field-text": "Text", "custom-fields": "Custom Fields", "date": "Date", + "date-format": "Date Format", + "date-format-yyyy-mm-dd": "YYYY-MM-DD", + "date-format-dd-mm-yyyy": "DD-MM-YYYY", + "date-format-mm-dd-yyyy": "MM-DD-YYYY", "decline": "Decline", "default-avatar": "Default avatar", "delete": "Delete", @@ -379,6 +398,7 @@ "editNotificationPopup-title": "Edit Notification", "editProfilePopup-title": "Edit Profile", "email": "Email", + "email-address": "Email Address", "email-enrollAccount-subject": "An account created for you on __siteName__", "email-enrollAccount-text": "Hello __user__,\n\nTo start using the service, simply click the link below.\n\n__url__\n\nThanks.", "email-fail": "Sending email failed", @@ -748,6 +768,8 @@ "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?", "delete-board": "Delete Board", + "delete-duplicate-lists": "Delete Duplicate Lists", + "delete-duplicate-lists-confirm": "Are you sure? This will delete all duplicate lists that have the same name and contain no cards.", "default-subtasks-board": "Subtasks for __board__ board", "default": "Default", "defaultdefault": "Default", @@ -755,7 +777,7 @@ "subtask-settings": "Subtasks Settings", "card-settings": "Card Settings", "minicard-settings": "Minicard Settings", - "boardSubtaskSettingsPopup-title": "Board Subtasks Settings", + "boardSubtaskSettingsPopup-title": "Subtasks Settings", "boardCardSettingsPopup-title": "Card Settings", "boardMinicardSettingsPopup-title": "Minicard Settings", "deposit-subtasks-board": "Deposit subtasks to this board:", @@ -1009,6 +1031,8 @@ "dueCardsViewChange-choice-me": "Me", "dueCardsViewChange-choice-all": "All Users", "dueCardsViewChange-choice-all-description": "Shows all incomplete cards with a *Due* date from boards for which the user has permission.", + "dueCards-noResults-title": "No Due Cards Found", + "dueCards-noResults-description": "You don't have any cards with due dates at the moment.", "broken-cards": "Broken Cards", "board-title-not-found": "Board '%s' not found.", "swimlane-title-not-found": "Swimlane '%s' not found.", @@ -1313,5 +1337,243 @@ "admin-people-user-active": "User is active - click to deactivate", "admin-people-user-inactive": "User is inactive - click to activate", "accounts-lockout-all-users-unlocked": "All locked users have been unlocked", - "accounts-lockout-unlock-all": "Unlock All" + "accounts-lockout-unlock-all": "Unlock All", + "active-cron-jobs": "Active Scheduled Jobs", + "add-cron-job": "Add Scheduled Job", + "add-cron-job-placeholder": "Add Scheduled Job functionality coming soon", + "attachment-storage-configuration": "Attachment Storage Configuration", + "attachments-path": "Attachments Path", + "attachments-path-description": "Path where attachment files are stored", + "avatars-path": "Avatars Path", + "avatars-path-description": "Path where avatar files are stored", + "board-archive-failed": "Failed to schedule board archive", + "board-archive-scheduled": "Board archive scheduled successfully", + "board-backup-failed": "Failed to schedule board backup", + "board-backup-scheduled": "Board backup scheduled successfully", + "board-cleanup-failed": "Failed to schedule board cleanup", + "board-cleanup-scheduled": "Board cleanup scheduled successfully", + "board-operations": "Board Operations", + "cron-jobs": "Scheduled Jobs", + "cron-migrations": "Scheduled Migrations", + "cron-job-delete-confirm": "Are you sure you want to delete this scheduled job?", + "cron-job-delete-failed": "Failed to delete scheduled job", + "cron-job-deleted": "Scheduled job deleted successfully", + "cron-job-pause-failed": "Failed to pause scheduled job", + "cron-job-paused": "Scheduled job paused successfully", + "filesystem-path-description": "Base path for file storage", + "gridfs-enabled": "GridFS Enabled", + "gridfs-enabled-description": "Use MongoDB GridFS for file storage", + "migration-pause-failed": "Failed to pause migrations", + "migration-paused": "Migrations paused successfully", + "migration-progress": "Migration Progress", + "migration-start-failed": "Failed to start migrations", + "migration-started": "Migrations started successfully", + "migration-status": "Migration Status", + "migration-stop-confirm": "Are you sure you want to stop all migrations?", + "migration-stop-failed": "Failed to stop migrations", + "migration-stopped": "Migrations stopped successfully", + "mongodb-gridfs-storage": "MongoDB GridFS Storage", + "pause-all-migrations": "Pause All Migrations", + "s3-access-key": "S3 Access Key", + "s3-access-key-description": "AWS S3 access key for authentication", + "s3-access-key-placeholder": "Enter S3 access key", + "s3-bucket": "S3 Bucket", + "s3-bucket-description": "S3 bucket name for storing files", + "s3-connection-failed": "S3 connection failed", + "s3-connection-success": "S3 connection successful", + "s3-enabled": "S3 Enabled", + "s3-enabled-description": "Use AWS S3 or MinIO for file storage", + "s3-endpoint": "S3 Endpoint", + "s3-endpoint-description": "S3 endpoint URL (e.g., s3.amazonaws.com or minio.example.com)", + "s3-minio-storage": "S3/MinIO Storage", + "s3-port": "S3 Port", + "s3-port-description": "S3 endpoint port number", + "s3-region": "S3 Region", + "s3-region-description": "AWS S3 region (e.g., us-east-1)", + "s3-secret-key": "S3 Secret Key", + "s3-secret-key-description": "AWS S3 secret key for authentication", + "s3-secret-key-placeholder": "Enter S3 secret key", + "s3-secret-key-required": "S3 secret key is required", + "s3-settings-save-failed": "Failed to save S3 settings", + "s3-settings-saved": "S3 settings saved successfully", + "s3-ssl-enabled": "S3 SSL Enabled", + "s3-ssl-enabled-description": "Use SSL/TLS for S3 connections", + "save-s3-settings": "Save S3 Settings", + "schedule-board-archive": "Schedule Board Archive", + "schedule-board-backup": "Schedule Board Backup", + "schedule-board-cleanup": "Schedule Board Cleanup", + "scheduled-board-operations": "Scheduled Board Operations", + "start-all-migrations": "Start All Migrations", + "stop-all-migrations": "Stop All Migrations", + "test-s3-connection": "Test S3 Connection", + "writable-path": "Writable Path", + "writable-path-description": "Base directory path for file storage", + "add-job": "Add Job", + "attachment-migration": "Attachment Migration", + "attachment-monitoring": "Attachment Monitoring", + "attachment-settings": "Attachment Settings", + "attachment-storage-settings": "Storage Settings", + "automatic-migration": "Automatic Migration", + "back-to-settings": "Back to Settings", + "board-id": "Board ID", + "board-migration": "Board Migration", + "board-migrations": "Board Migrations", + "card-show-lists-on-minicard": "Show Lists on Minicard", + "comprehensive-board-migration": "Comprehensive Board Migration", + "comprehensive-board-migration-description": "Performs comprehensive checks and fixes for board data integrity, including list ordering, card positions, and swimlane structure.", + "delete-duplicate-empty-lists-migration": "Delete Duplicate Empty Lists", + "delete-duplicate-empty-lists-migration-description": "Safely deletes empty duplicate lists. Only removes lists that have no cards AND have another list with the same title that contains cards.", + "lost-cards": "Lost Cards", + "lost-cards-list": "Restored Items", + "restore-lost-cards-migration": "Restore Lost Cards", + "restore-lost-cards-migration-description": "Finds and restores cards and lists with missing swimlaneId or listId. Creates a 'Lost Cards' swimlane to make all lost items visible again.", + "restore-all-archived-migration": "Restore All Archived", + "restore-all-archived-migration-description": "Restores all archived swimlanes, lists, and cards. Automatically fixes any missing swimlaneId or listId to make items visible.", + "fix-missing-lists-migration": "Fix Missing Lists", + "fix-missing-lists-migration-description": "Detects and repairs missing or corrupted lists in the board structure.", + "fix-avatar-urls-migration": "Fix Avatar URLs", + "fix-avatar-urls-migration-description": "Updates avatar URLs for board members to use the correct storage backend and fixes broken avatar references.", + "fix-all-file-urls-migration": "Fix All File URLs", + "fix-all-file-urls-migration-description": "Updates all file attachment URLs on this board to use the correct storage backend and fixes broken file references.", + "migration-needed": "Migration Needed", + "migration-complete": "Complete", + "migration-running": "Running...", + "migration-successful": "Migration completed successfully", + "migration-failed": "Migration failed", + "migrations": "Migrations", + "migrations-admin-only": "Only board administrators can run migrations", + "migrations-description": "Run data integrity checks and repairs for this board. Each migration can be executed individually.", + "no-issues-found": "No issues found", + "run-migration": "Run Migration", + "run-comprehensive-migration-confirm": "This will perform a comprehensive migration to check and fix board data integrity. This may take a few moments. Continue?", + "run-delete-duplicate-empty-lists-migration-confirm": "This will first convert any shared lists to per-swimlane lists, then delete empty lists that have a duplicate list with the same title containing cards. Only truly redundant empty lists will be removed. Continue?", + "run-restore-lost-cards-migration-confirm": "This will create a 'Lost Cards' swimlane and restore all cards and lists with missing swimlaneId or listId. This only affects non-archived items. Continue?", + "run-restore-all-archived-migration-confirm": "This will restore ALL archived swimlanes, lists, and cards, making them visible again. Any items with missing IDs will be automatically fixed. This cannot be easily undone. Continue?", + "run-fix-missing-lists-migration-confirm": "This will detect and repair missing or corrupted lists in the board structure. Continue?", + "run-fix-avatar-urls-migration-confirm": "This will update avatar URLs for board members to use the correct storage backend. Continue?", + "run-fix-all-file-urls-migration-confirm": "This will update all file attachment URLs on this board to use the correct storage backend. Continue?", + "restore-lost-cards-nothing-to-restore": "No lost swimlanes, lists, or cards to restore", + + "migration-progress-title": "Board Migration in Progress", + "migration-progress-overall": "Overall Progress", + "migration-progress-current-step": "Current Step", + "migration-progress-status": "Status", + "migration-progress-details": "Details", + "migration-progress-note": "Please wait while we migrate your board to the latest structure...", + + "step-analyze-board-structure": "Analyze Board Structure", + "step-fix-orphaned-cards": "Fix Orphaned Cards", + "step-convert-shared-lists": "Convert Shared Lists", + "step-ensure-per-swimlane-lists": "Ensure Per-Swimlane Lists", + "step-validate-migration": "Validate Migration", + "step-fix-avatar-urls": "Fix Avatar URLs", + "step-fix-attachment-urls": "Fix Attachment URLs", + "step-analyze-lists": "Analyze Lists", + "step-create-missing-lists": "Create Missing Lists", + "step-update-cards": "Update Cards", + "step-finalize": "Finalize", + "step-delete-duplicate-empty-lists": "Delete Duplicate Empty Lists", + "step-ensure-lost-cards-swimlane": "Ensure Lost Cards Swimlane", + "step-restore-lists": "Restore Lists", + "step-restore-cards": "Restore Cards", + "step-restore-swimlanes": "Restore Swimlanes", + "step-fix-missing-ids": "Fix Missing IDs", + "step-scan-users": "Checking board member avatars", + "step-scan-files": "Checking board file attachments", + "step-fix-file-urls": "Fixing file URLs", + "cleanup": "Cleanup", + "cleanup-old-jobs": "Cleanup Old Jobs", + "completed": "Completed", + "conversion-info-text": "This conversion is performed once per board and improves performance. You can continue using the board normally.", + "converting-board": "Converting Board", + "converting-board-description": "Converting board structure for improved functionality. This may take a few moments.", + "cpu-cores": "CPU Cores", + "cpu-usage": "CPU Usage", + "current-action": "Current Action", + "database-migration": "Database Migration", + "database-migration-description": "Updating database structure for improved functionality and performance. This process may take several minutes.", + "database-migrations": "Database Migrations", + "days-old": "Days Old", + "duration": "Duration", + "errors": "Errors", + "estimated-time-remaining": "Estimated time remaining", + "every-1-day": "Every 1 day", + "every-1-hour": "Every 1 hour", + "every-1-minute": "Every 1 minute", + "every-10-minutes": "Every 10 minutes", + "every-30-minutes": "Every 30 minutes", + "every-5-minutes": "Every 5 minutes", + "every-6-hours": "Every 6 hours", + "export-monitoring": "Export Monitoring", + "filesystem-attachments": "Filesystem Attachments", + "filesystem-size": "Filesystem Size", + "filesystem-storage": "Filesystem Storage", + "force-board-scan": "Force Board Scan", + "gridfs-attachments": "GridFS Attachments", + "gridfs-size": "GridFS Size", + "gridfs-storage": "GridFS", + "hide-list-on-minicard": "Hide List on Minicard", + "idle-migration": "Idle Migration", + "job-description": "Job Description", + "job-details": "Job Details", + "job-name": "Job Name", + "job-queue": "Job Queue", + "last-run": "Last Run", + "max-concurrent": "Max Concurrent", + "memory-usage": "Memory Usage", + "migrate-all-to-filesystem": "Migrate All to Filesystem", + "migrate-all-to-gridfs": "Migrate All to GridFS", + "migrate-all-to-s3": "Migrate All to S3", + "migrated-attachments": "Migrated Attachments", + "migration-batch-size": "Batch Size", + "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", + "migration-cpu-threshold": "CPU Threshold (%)", + "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", + "migration-delay-ms": "Delay (ms)", + "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", + "migration-detector": "Migration Detector", + "migration-info-text": "Database migrations are performed once and improve system performance. The process continues in the background even if you close your browser.", + "migration-log": "Migration Log", + "migration-markers": "Migration Markers", + "migration-resume-failed": "Failed to resume migration", + "migration-resumed": "Migration resumed", + "migration-steps": "Migration Steps", + "migration-warning-text": "Please do not close your browser during migration. The process will continue in the background but may take longer to complete.", + "monitoring-export-failed": "Failed to export monitoring data", + "monitoring-refresh-failed": "Failed to refresh monitoring data", + "next": "Next", + "next-run": "Next Run", + "of": "of", + "operation-type": "Operation Type", + "overall-progress": "Overall Progress", + "page": "Page", + "pause-migration": "Pause Migration", + "previous": "Previous", + "refresh": "Refresh", + "refresh-monitoring": "Refresh Monitoring", + "remaining-attachments": "Remaining Attachments", + "resume-migration": "Resume Migration", + "run-once": "Run once", + "s3-attachments": "S3 Attachments", + "s3-size": "S3 Size", + "s3-storage": "S3", + "scanning-status": "Scanning Status", + "schedule": "Schedule", + "search-boards-or-operations": "Search boards or operations...", + "show-list-on-minicard": "Show List on Minicard", + "showing": "Showing", + "start-test-operation": "Start Test Operation", + "start-time": "Start Time", + "step-progress": "Step Progress", + "stop-migration": "Stop Migration", + "storage-distribution": "Storage Distribution", + "system-resources": "System Resources", + "total-attachments": "Total Attachments", + "total-operations": "Total Operations", + "total-size": "Total Size", + "unmigrated-boards": "Unmigrated Boards", + "weight": "Weight", + "idle": "Idle", + "complete": "Complete", + "cron": "Cron" } diff --git a/imports/i18n/en.i18n.json b/imports/i18n/en.i18n.json deleted file mode 100644 index f54b3a327..000000000 --- a/imports/i18n/en.i18n.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "attachment-settings": "Attachment Settings", - "attachment-storage-settings": "Storage Settings", - "attachment-migration": "Migration", - "attachment-monitoring": "Monitoring", - "attachment-storage-configuration": "Storage Configuration", - "filesystem-storage": "Filesystem Storage", - "writable-path": "Writable Path", - "filesystem-path-description": "Base path for file storage", - "attachments-path": "Attachments Path", - "attachments-path-description": "Path for attachment files", - "avatars-path": "Avatars Path", - "avatars-path-description": "Path for avatar files", - "mongodb-gridfs-storage": "MongoDB GridFS Storage", - "gridfs-enabled": "GridFS Enabled", - "gridfs-enabled-description": "MongoDB GridFS storage is always available", - "s3-minio-storage": "S3/MinIO Storage", - "s3-enabled": "S3 Enabled", - "s3-enabled-description": "S3/MinIO storage configuration", - "s3-endpoint": "S3 Endpoint", - "s3-endpoint-description": "S3/MinIO server endpoint", - "s3-bucket": "S3 Bucket", - "s3-bucket-description": "S3/MinIO bucket name", - "s3-region": "S3 Region", - "s3-region-description": "S3 region", - "s3-access-key": "S3 Access Key", - "s3-access-key-placeholder": "Access key is configured via environment", - "s3-access-key-description": "S3/MinIO access key", - "s3-secret-key": "S3 Secret Key", - "s3-secret-key-placeholder": "Enter new secret key to update", - "s3-secret-key-description": "S3/MinIO secret key (only save new ones)", - "s3-ssl-enabled": "SSL Enabled", - "s3-ssl-enabled-description": "Use SSL for S3/MinIO connections", - "s3-port": "S3 Port", - "s3-port-description": "S3/MinIO server port", - "test-s3-connection": "Test S3 Connection", - "save-s3-settings": "Save S3 Settings", - "s3-connection-success": "S3 connection test successful", - "s3-connection-failed": "S3 connection test failed", - "s3-settings-saved": "S3 settings saved successfully", - "s3-settings-save-failed": "Failed to save S3 settings", - "s3-secret-key-required": "S3 secret key is required", - "attachment-migration": "Attachment Migration", - "migration-batch-size": "Batch Size", - "migration-batch-size-description": "Number of attachments to process in each batch (1-100)", - "migration-delay-ms": "Delay (ms)", - "migration-delay-ms-description": "Delay between batches in milliseconds (100-10000)", - "migration-cpu-threshold": "CPU Threshold (%)", - "migration-cpu-threshold-description": "Pause migration when CPU usage exceeds this percentage (10-90)", - "migrate-all-to-filesystem": "Migrate All to Filesystem", - "migrate-all-to-gridfs": "Migrate All to GridFS", - "migrate-all-to-s3": "Migrate All to S3", - "pause-migration": "Pause Migration", - "resume-migration": "Resume Migration", - "stop-migration": "Stop Migration", - "migration-progress": "Migration Progress", - "total-attachments": "Total Attachments", - "migrated-attachments": "Migrated Attachments", - "remaining-attachments": "Remaining Attachments", - "migration-status": "Migration Status", - "migration-log": "Migration Log", - "migration-started": "Migration started", - "migration-paused": "Migration paused", - "migration-resumed": "Migration resumed", - "migration-stopped": "Migration stopped", - "migration-start-failed": "Failed to start migration", - "migration-pause-failed": "Failed to pause migration", - "migration-resume-failed": "Failed to resume migration", - "migration-stop-failed": "Failed to stop migration", - "migration-stop-confirm": "Are you sure you want to stop the migration?", - "attachment-monitoring": "Attachment Monitoring", - "filesystem-attachments": "Filesystem Attachments", - "gridfs-attachments": "GridFS Attachments", - "s3-attachments": "S3 Attachments", - "total-size": "Total Size", - "filesystem-size": "Filesystem Size", - "gridfs-size": "GridFS Size", - "s3-size": "S3 Size", - "storage-distribution": "Storage Distribution", - "refresh-monitoring": "Refresh Monitoring", - "export-monitoring": "Export Monitoring", - "monitoring-refresh-failed": "Failed to refresh monitoring data", - "monitoring-export-failed": "Failed to export monitoring data", - "filesystem-storage": "Filesystem", - "gridfs-storage": "GridFS", - "s3-storage": "S3", - "card-show-lists-on-minicard": "Show Lists on Minicard", - "show-list-on-minicard": "Show List on Minicard", - "hide-list-on-minicard": "Hide List on Minicard" -} diff --git a/imports/i18n/index.js b/imports/i18n/index.js index c8e39e358..b18a217cc 100644 --- a/imports/i18n/index.js +++ b/imports/i18n/index.js @@ -1,6 +1,5 @@ import { TAPi18n } from './tap'; import './accounts'; -import './moment'; if (Meteor.isClient) { import './blaze'; diff --git a/imports/i18n/moment.js b/imports/i18n/moment.js index 998e45f86..a2a378eee 100644 --- a/imports/i18n/moment.js +++ b/imports/i18n/moment.js @@ -1,13 +1,5 @@ import { Tracker } from 'meteor/tracker'; -import moment from 'moment/min/moment-with-locales'; import { TAPi18n } from './tap'; -// Reactively adjust Moment.js translations -Tracker.autorun(() => { - const language = TAPi18n.getLanguage(); - try { - moment.locale(language); - } catch (err) { - console.error(err); - } -}); +// Note: moment.js has been removed and replaced with native JavaScript Date functions +// Locale handling is now done through native Date.toLocaleString() methods diff --git a/imports/lib/dateUtils.js b/imports/lib/dateUtils.js new file mode 100644 index 000000000..884763488 --- /dev/null +++ b/imports/lib/dateUtils.js @@ -0,0 +1,571 @@ +/** + * Date utility functions to replace moment.js with native JavaScript Date + */ + +/** + * Format a date to YYYY-MM-DD HH:mm format + * @param {Date|string} date - Date to format + * @returns {string} Formatted date string + */ +export function formatDateTime(date) { + const d = new Date(date); + if (isNaN(d.getTime())) return ''; + + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + const hours = String(d.getHours()).padStart(2, '0'); + const minutes = String(d.getMinutes()).padStart(2, '0'); + + return `${year}-${month}-${day} ${hours}:${minutes}`; +} + +/** + * Format a date to YYYY-MM-DD format + * @param {Date|string} date - Date to format + * @returns {string} Formatted date string + */ +export function formatDate(date) { + const d = new Date(date); + if (isNaN(d.getTime())) return ''; + + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + + return `${year}-${month}-${day}`; +} + +/** + * Format a date according to user's preferred format + * @param {Date|string} date - Date to format + * @param {string} format - Format string (YYYY-MM-DD, DD-MM-YYYY, MM-DD-YYYY) + * @param {boolean} includeTime - Whether to include time (HH:MM) + * @returns {string} Formatted date string + */ +export function formatDateByUserPreference(date, format = 'YYYY-MM-DD', includeTime = true) { + const d = new Date(date); + if (isNaN(d.getTime())) return ''; + + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + const hours = String(d.getHours()).padStart(2, '0'); + const minutes = String(d.getMinutes()).padStart(2, '0'); + + let dateString; + switch (format) { + case 'DD-MM-YYYY': + dateString = `${day}-${month}-${year}`; + break; + case 'MM-DD-YYYY': + dateString = `${month}-${day}-${year}`; + break; + case 'YYYY-MM-DD': + default: + dateString = `${year}-${month}-${day}`; + break; + } + + if (includeTime) { + return `${dateString} ${hours}:${minutes}`; + } + + return dateString; +} + +/** + * Format a time to HH:mm format + * @param {Date|string} date - Date to format + * @returns {string} Formatted time string + */ +export function formatTime(date) { + const d = new Date(date); + if (isNaN(d.getTime())) return ''; + + const hours = String(d.getHours()).padStart(2, '0'); + const minutes = String(d.getMinutes()).padStart(2, '0'); + + return `${hours}:${minutes}`; +} + +/** + * Get ISO week number (ISO 8601) + * @param {Date|string} date - Date to get week number for + * @returns {number} ISO week number + */ +export function getISOWeek(date) { + const d = new Date(date); + if (isNaN(d.getTime())) return 0; + + // Set to nearest Thursday: current date + 4 - current day number + // Make Sunday's day number 7 + const target = new Date(d); + const dayNr = (d.getDay() + 6) % 7; + target.setDate(target.getDate() - dayNr + 3); + + // ISO week date weeks start on monday, so correct the day number + const firstThursday = target.valueOf(); + target.setMonth(0, 1); + if (target.getDay() !== 4) { + target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7); + } + + return 1 + Math.ceil((firstThursday - target) / 604800000); // 604800000 = 7 * 24 * 3600 * 1000 +} + +/** + * Check if a date is valid + * @param {Date|string} date - Date to check + * @returns {boolean} True if date is valid + */ +export function isValidDate(date) { + const d = new Date(date); + return !isNaN(d.getTime()); +} + +/** + * Check if a date is before another date + * @param {Date|string} date1 - First date + * @param {Date|string} date2 - Second date + * @param {string} unit - Unit of comparison ('minute', 'hour', 'day', etc.) + * @returns {boolean} True if date1 is before date2 + */ +export function isBefore(date1, date2, unit = 'millisecond') { + const d1 = new Date(date1); + const d2 = new Date(date2); + + if (isNaN(d1.getTime()) || isNaN(d2.getTime())) return false; + + switch (unit) { + case 'year': + return d1.getFullYear() < d2.getFullYear(); + case 'month': + return d1.getFullYear() < d2.getFullYear() || + (d1.getFullYear() === d2.getFullYear() && d1.getMonth() < d2.getMonth()); + case 'day': + return d1.getFullYear() < d2.getFullYear() || + (d1.getFullYear() === d2.getFullYear() && d1.getMonth() < d2.getMonth()) || + (d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() < d2.getDate()); + case 'hour': + return d1.getTime() < d2.getTime() && Math.floor(d1.getTime() / (1000 * 60 * 60)) < Math.floor(d2.getTime() / (1000 * 60 * 60)); + case 'minute': + return d1.getTime() < d2.getTime() && Math.floor(d1.getTime() / (1000 * 60)) < Math.floor(d2.getTime() / (1000 * 60)); + default: + return d1.getTime() < d2.getTime(); + } +} + +/** + * Check if a date is after another date + * @param {Date|string} date1 - First date + * @param {Date|string} date2 - Second date + * @param {string} unit - Unit of comparison ('minute', 'hour', 'day', etc.) + * @returns {boolean} True if date1 is after date2 + */ +export function isAfter(date1, date2, unit = 'millisecond') { + return isBefore(date2, date1, unit); +} + +/** + * Check if a date is the same as another date + * @param {Date|string} date1 - First date + * @param {Date|string} date2 - Second date + * @param {string} unit - Unit of comparison ('minute', 'hour', 'day', etc.) + * @returns {boolean} True if dates are the same + */ +export function isSame(date1, date2, unit = 'millisecond') { + const d1 = new Date(date1); + const d2 = new Date(date2); + + if (isNaN(d1.getTime()) || isNaN(d2.getTime())) return false; + + switch (unit) { + case 'year': + return d1.getFullYear() === d2.getFullYear(); + case 'month': + return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth(); + case 'day': + return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate(); + case 'hour': + return Math.floor(d1.getTime() / (1000 * 60 * 60)) === Math.floor(d2.getTime() / (1000 * 60 * 60)); + case 'minute': + return Math.floor(d1.getTime() / (1000 * 60)) === Math.floor(d2.getTime() / (1000 * 60)); + default: + return d1.getTime() === d2.getTime(); + } +} + +/** + * Add time to a date + * @param {Date|string} date - Base date + * @param {number} amount - Amount to add + * @param {string} unit - Unit ('years', 'months', 'days', 'hours', 'minutes', 'seconds') + * @returns {Date} New date + */ +export function add(date, amount, unit) { + const d = new Date(date); + if (isNaN(d.getTime())) return new Date(); + + switch (unit) { + case 'years': + d.setFullYear(d.getFullYear() + amount); + break; + case 'months': + d.setMonth(d.getMonth() + amount); + break; + case 'days': + d.setDate(d.getDate() + amount); + break; + case 'hours': + d.setHours(d.getHours() + amount); + break; + case 'minutes': + d.setMinutes(d.getMinutes() + amount); + break; + case 'seconds': + d.setSeconds(d.getSeconds() + amount); + break; + default: + d.setTime(d.getTime() + amount); + } + + return d; +} + +/** + * Subtract time from a date + * @param {Date|string} date - Base date + * @param {number} amount - Amount to subtract + * @param {string} unit - Unit ('years', 'months', 'days', 'hours', 'minutes', 'seconds') + * @returns {Date} New date + */ +export function subtract(date, amount, unit) { + return add(date, -amount, unit); +} + +/** + * Get start of a time unit + * @param {Date|string} date - Base date + * @param {string} unit - Unit ('year', 'month', 'day', 'hour', 'minute', 'second') + * @returns {Date} Start of unit + */ +export function startOf(date, unit) { + const d = new Date(date); + if (isNaN(d.getTime())) return new Date(); + + switch (unit) { + case 'year': + d.setMonth(0, 1); + d.setHours(0, 0, 0, 0); + break; + case 'month': + d.setDate(1); + d.setHours(0, 0, 0, 0); + break; + case 'day': + d.setHours(0, 0, 0, 0); + break; + case 'hour': + d.setMinutes(0, 0, 0); + break; + case 'minute': + d.setSeconds(0, 0); + break; + case 'second': + d.setMilliseconds(0); + break; + } + + return d; +} + +/** + * Get end of a time unit + * @param {Date|string} date - Base date + * @param {string} unit - Unit ('year', 'month', 'day', 'hour', 'minute', 'second') + * @returns {Date} End of unit + */ +export function endOf(date, unit) { + const d = new Date(date); + if (isNaN(d.getTime())) return new Date(); + + switch (unit) { + case 'year': + d.setMonth(11, 31); + d.setHours(23, 59, 59, 999); + break; + case 'month': + d.setMonth(d.getMonth() + 1, 0); + d.setHours(23, 59, 59, 999); + break; + case 'day': + d.setHours(23, 59, 59, 999); + break; + case 'hour': + d.setMinutes(59, 59, 999); + break; + case 'minute': + d.setSeconds(59, 999); + break; + case 'second': + d.setMilliseconds(999); + break; + } + + return d; +} + +/** + * Format date for display with locale + * @param {Date|string} date - Date to format + * @param {string} format - Format string (simplified) + * @returns {string} Formatted date string + */ +export function format(date, format = 'L') { + const d = new Date(date); + if (isNaN(d.getTime())) return ''; + + const year = d.getFullYear(); + const month = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + const hours = String(d.getHours()).padStart(2, '0'); + const minutes = String(d.getMinutes()).padStart(2, '0'); + const seconds = String(d.getSeconds()).padStart(2, '0'); + + switch (format) { + case 'L': + return `${month}/${day}/${year}`; + case 'LL': + return d.toLocaleDateString(); + case 'LLL': + return d.toLocaleString(); + case 'llll': + return d.toLocaleString(); + case 'LLLL': + return d.toLocaleString(); + case 'l LT': + return `${month}/${day}/${year} ${hours}:${minutes}`; + case 'YYYY-MM-DD': + return `${year}-${month}-${day}`; + case 'YYYY-MM-DD HH:mm': + return `${year}-${month}-${day} ${hours}:${minutes}`; + case 'HH:mm': + return `${hours}:${minutes}`; + default: + return d.toLocaleString(); + } +} + +/** + * Parse a date string with multiple formats + * @param {string} dateString - Date string to parse + * @param {string[]} formats - Array of format strings to try + * @param {boolean} strict - Whether to use strict parsing + * @returns {Date|null} Parsed date or null if invalid + */ +export function parseDate(dateString, formats = [], strict = true) { + if (!dateString) return null; + + // Try native Date parsing first + const nativeDate = new Date(dateString); + if (!isNaN(nativeDate.getTime())) { + return nativeDate; + } + + // Try common formats + const commonFormats = [ + 'YYYY-MM-DD HH:mm', + 'YYYY-MM-DD', + 'MM/DD/YYYY HH:mm', + 'MM/DD/YYYY', + 'DD.MM.YYYY HH:mm', + 'DD.MM.YYYY', + 'DD/MM/YYYY HH:mm', + 'DD/MM/YYYY', + 'DD-MM-YYYY HH:mm', + 'DD-MM-YYYY' + ]; + + const allFormats = [...formats, ...commonFormats]; + + for (const format of allFormats) { + const parsed = parseWithFormat(dateString, format); + if (parsed && isValidDate(parsed)) { + return parsed; + } + } + + return null; +} + +/** + * Parse date with specific format + * @param {string} dateString - Date string to parse + * @param {string} format - Format string + * @returns {Date|null} Parsed date or null + */ +function parseWithFormat(dateString, format) { + // Simple format parsing - can be extended as needed + const formatMap = { + 'YYYY': '\\d{4}', + 'MM': '\\d{2}', + 'DD': '\\d{2}', + 'HH': '\\d{2}', + 'mm': '\\d{2}', + 'ss': '\\d{2}' + }; + + let regex = format; + for (const [key, value] of Object.entries(formatMap)) { + regex = regex.replace(new RegExp(key, 'g'), `(${value})`); + } + + const match = dateString.match(new RegExp(regex)); + if (!match) return null; + + const groups = match.slice(1); + let year, month, day, hour = 0, minute = 0, second = 0; + + let groupIndex = 0; + for (let i = 0; i < format.length; i++) { + if (format[i] === 'Y' && format[i + 1] === 'Y' && format[i + 2] === 'Y' && format[i + 3] === 'Y') { + year = parseInt(groups[groupIndex++]); + i += 3; + } else if (format[i] === 'M' && format[i + 1] === 'M') { + month = parseInt(groups[groupIndex++]) - 1; + i += 1; + } else if (format[i] === 'D' && format[i + 1] === 'D') { + day = parseInt(groups[groupIndex++]); + i += 1; + } else if (format[i] === 'H' && format[i + 1] === 'H') { + hour = parseInt(groups[groupIndex++]); + i += 1; + } else if (format[i] === 'm' && format[i + 1] === 'm') { + minute = parseInt(groups[groupIndex++]); + i += 1; + } else if (format[i] === 's' && format[i + 1] === 's') { + second = parseInt(groups[groupIndex++]); + i += 1; + } + } + + if (year === undefined || month === undefined || day === undefined) { + return null; + } + + return new Date(year, month, day, hour, minute, second); +} + +/** + * Get current date and time + * @returns {Date} Current date + */ +export function now() { + return new Date(); +} + +/** + * Create a date from components + * @param {number} year - Year + * @param {number} month - Month (0-based) + * @param {number} day - Day + * @param {number} hour - Hour (optional) + * @param {number} minute - Minute (optional) + * @param {number} second - Second (optional) + * @returns {Date} Created date + */ +export function createDate(year, month, day, hour = 0, minute = 0, second = 0) { + return new Date(year, month, day, hour, minute, second); +} + +/** + * Get relative time string (e.g., "2 hours ago") + * @param {Date|string} date - Date to compare + * @param {Date|string} now - Current date (optional) + * @returns {string} Relative time string + */ +export function fromNow(date, now = new Date()) { + const d = new Date(date); + const n = new Date(now); + + if (isNaN(d.getTime()) || isNaN(n.getTime())) return ''; + + const diffMs = n.getTime() - d.getTime(); + const diffSeconds = Math.floor(diffMs / 1000); + const diffMinutes = Math.floor(diffSeconds / 60); + const diffHours = Math.floor(diffMinutes / 60); + const diffDays = Math.floor(diffHours / 24); + const diffWeeks = Math.floor(diffDays / 7); + const diffMonths = Math.floor(diffDays / 30); + const diffYears = Math.floor(diffDays / 365); + + if (diffSeconds < 60) return 'a few seconds ago'; + if (diffMinutes < 60) return `${diffMinutes} minute${diffMinutes !== 1 ? 's' : ''} ago`; + if (diffHours < 24) return `${diffHours} hour${diffHours !== 1 ? 's' : ''} ago`; + if (diffDays < 7) return `${diffDays} day${diffDays !== 1 ? 's' : ''} ago`; + if (diffWeeks < 4) return `${diffWeeks} week${diffWeeks !== 1 ? 's' : ''} ago`; + if (diffMonths < 12) return `${diffMonths} month${diffMonths !== 1 ? 's' : ''} ago`; + return `${diffYears} year${diffYears !== 1 ? 's' : ''} ago`; +} + +/** + * Get calendar format (e.g., "Today", "Yesterday", "Tomorrow") + * @param {Date|string} date - Date to format + * @param {Date|string} now - Current date (optional) + * @returns {string} Calendar format string + */ +export function calendar(date, now = new Date()) { + const d = new Date(date); + const n = new Date(now); + + if (isNaN(d.getTime()) || isNaN(n.getTime())) return format(d); + + const diffMs = d.getTime() - n.getTime(); + const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); + + if (diffDays === 0) return 'Today'; + if (diffDays === 1) return 'Tomorrow'; + if (diffDays === -1) return 'Yesterday'; + if (diffDays > 1 && diffDays < 7) return `In ${diffDays} days`; + if (diffDays < -1 && diffDays > -7) return `${Math.abs(diffDays)} days ago`; + + return format(d, 'L'); +} + +/** + * Calculate the difference between two dates in the specified unit + * @param {Date|string} date1 - First date + * @param {Date|string} date2 - Second date + * @param {string} unit - Unit of measurement ('millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'year') + * @returns {number} Difference in the specified unit + */ +export function diff(date1, date2, unit = 'millisecond') { + const d1 = new Date(date1); + const d2 = new Date(date2); + + if (isNaN(d1.getTime()) || isNaN(d2.getTime())) return 0; + + const diffMs = d1.getTime() - d2.getTime(); + + switch (unit) { + case 'millisecond': + return diffMs; + case 'second': + return Math.floor(diffMs / 1000); + case 'minute': + return Math.floor(diffMs / (1000 * 60)); + case 'hour': + return Math.floor(diffMs / (1000 * 60 * 60)); + case 'day': + return Math.floor(diffMs / (1000 * 60 * 60 * 24)); + case 'week': + return Math.floor(diffMs / (1000 * 60 * 60 * 24 * 7)); + case 'month': + return Math.floor(diffMs / (1000 * 60 * 60 * 24 * 30)); + case 'year': + return Math.floor(diffMs / (1000 * 60 * 60 * 24 * 365)); + default: + return diffMs; + } +} diff --git a/imports/lib/secureDOMPurify.js b/imports/lib/secureDOMPurify.js index 4deee4d23..898687dad 100644 --- a/imports/lib/secureDOMPurify.js +++ b/imports/lib/secureDOMPurify.js @@ -3,43 +3,25 @@ import DOMPurify from 'dompurify'; // Centralized secure DOMPurify configuration to prevent XSS and CSS injection attacks export function getSecureDOMPurifyConfig() { return { - // Block dangerous elements that can cause XSS and CSS injection - FORBID_TAGS: [ - 'svg', 'defs', 'use', 'g', 'symbol', 'marker', 'pattern', 'mask', 'clipPath', - 'linearGradient', 'radialGradient', 'stop', 'animate', 'animateTransform', - 'animateMotion', 'set', 'switch', 'foreignObject', 'script', 'style', 'link', - 'meta', 'iframe', 'object', 'embed', 'applet', 'form', 'input', 'textarea', - 'select', 'option', 'button', 'label', 'fieldset', 'legend', 'frameset', - 'frame', 'noframes', 'base', 'basefont', 'isindex', 'dir', 'menu', 'menuitem' - ], - // Block dangerous attributes that can cause XSS and CSS injection - FORBID_ATTR: [ - 'xlink:href', 'href', 'onload', 'onerror', 'onclick', 'onmouseover', - 'onfocus', 'onblur', 'onchange', 'onsubmit', 'onreset', 'onselect', - 'onunload', 'onresize', 'onscroll', 'onkeydown', 'onkeyup', 'onkeypress', - 'onmousedown', 'onmouseup', 'onmouseover', 'onmouseout', 'onmousemove', - 'ondblclick', 'oncontextmenu', 'onwheel', 'ontouchstart', 'ontouchend', - 'ontouchmove', 'ontouchcancel', 'onabort', 'oncanplay', 'oncanplaythrough', - 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onloadeddata', - 'onloadedmetadata', 'onloadstart', 'onpause', 'onplay', 'onplaying', - 'onprogress', 'onratechange', 'onseeked', 'onseeking', 'onstalled', - 'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting', 'onbeforeunload', - 'onhashchange', 'onpagehide', 'onpageshow', 'onpopstate', 'onstorage', - 'onunload', 'style', 'class', 'id', 'data-*', 'aria-*' - ], - // Allow only safe image formats and protocols + // Allow common markdown elements including anchor tags + ALLOWED_TAGS: ['a', 'p', 'br', 'strong', 'em', 'u', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'img', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'hr', 'div', 'span'], + // Allow safe attributes including href for anchor tags + ALLOWED_ATTR: ['href', 'title', 'alt', 'src', 'width', 'height', 'target', 'rel'], + // Allow safe protocols for links ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i, - // Remove dangerous protocols + // Allow unknown protocols but be cautious ALLOW_UNKNOWN_PROTOCOLS: false, - // Sanitize URLs to prevent malicious content loading + // Sanitize DOM for security SANITIZE_DOM: true, - // Remove dangerous elements completely - KEEP_CONTENT: false, - // Additional security measures - ADD_ATTR: [], + // Keep content but sanitize it + KEEP_CONTENT: true, + // Block dangerous elements that can cause XSS + FORBID_TAGS: ['script', 'style', 'iframe', 'object', 'embed', 'applet', 'svg', 'defs', 'use', 'g', 'symbol', 'marker', 'pattern', 'mask', 'clipPath', 'linearGradient', 'radialGradient', 'stop', 'animate', 'animateTransform', 'animateMotion', 'set', 'switch', 'foreignObject', 'link', 'meta', 'form', 'input', 'textarea', 'select', 'option', 'button', 'label', 'fieldset', 'legend', 'frameset', 'frame', 'noframes', 'base', 'basefont', 'isindex', 'dir', 'menu', 'menuitem'], + // Block dangerous attributes but allow safe href + FORBID_ATTR: ['xlink:href', 'onload', 'onerror', 'onclick', 'onmouseover', 'onfocus', 'onblur', 'onchange', 'onsubmit', 'onreset', 'onselect', 'onunload', 'onresize', 'onscroll', 'onkeydown', 'onkeyup', 'onkeypress', 'onmousedown', 'onmouseup', 'onmouseover', 'onmouseout', 'onmousemove', 'ondblclick', 'oncontextmenu', 'onwheel', 'ontouchstart', 'ontouchend', 'ontouchmove', 'ontouchcancel', 'onabort', 'oncanplay', 'oncanplaythrough', 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onpause', 'onplay', 'onplaying', 'onprogress', 'onratechange', 'onseeked', 'onseeking', 'onstalled', 'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting', 'onbeforeunload', 'onhashchange', 'onpagehide', 'onpageshow', 'onpopstate', 'onstorage', 'onunload', 'style', 'class', 'id', 'data-*', 'aria-*'], // Block data URIs that could contain malicious content ALLOW_DATA_ATTR: false, - // Custom hook to further sanitize content + // Custom hooks for additional security HOOKS: { uponSanitizeElement: function(node, data) { // Block any remaining dangerous elements @@ -123,6 +105,19 @@ export function getSecureDOMPurifyConfig() { return false; } + // Allow href attribute for anchor tags only + if (data.attrName === 'href') { + // Only allow href on anchor tags + if (node.tagName && node.tagName.toLowerCase() === 'a') { + return true; + } else { + if (process.env.DEBUG === 'true') { + console.warn('Blocked href attribute on non-anchor element:', node.tagName); + } + return false; + } + } + return true; } } diff --git a/models/attachmentStorageSettings.js b/models/attachmentStorageSettings.js index 8f67c5160..f0a67271c 100644 --- a/models/attachmentStorageSettings.js +++ b/models/attachmentStorageSettings.js @@ -1,7 +1,9 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { Meteor } from 'meteor/meteor'; import { SimpleSchema } from 'meteor/aldeed:simple-schema'; -import { STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS, STORAGE_NAME_S3 } from '/models/lib/fileStoreStrategy'; +import { STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS } from '/models/lib/fileStoreStrategy'; +// DISABLED: S3 storage removed due to Node.js compatibility +// import { STORAGE_NAME_S3 } from '/models/lib/fileStoreStrategy'; // Attachment Storage Settings Collection AttachmentStorageSettings = new Mongo.Collection('attachmentStorageSettings'); @@ -12,7 +14,7 @@ AttachmentStorageSettings.attachSchema( // Default storage backend for new uploads defaultStorage: { type: String, - allowedValues: [STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS, STORAGE_NAME_S3], + allowedValues: [STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS], defaultValue: STORAGE_NAME_FILESYSTEM, label: 'Default Storage Backend' }, @@ -54,6 +56,8 @@ AttachmentStorageSettings.attachSchema( label: 'GridFS Storage Enabled' }, + // DISABLED: S3 storage configuration removed due to Node.js compatibility + /* 'storageConfig.s3': { type: Object, optional: true, @@ -95,6 +99,7 @@ AttachmentStorageSettings.attachSchema( defaultValue: 443, label: 'S3 Port' }, + */ // Upload settings uploadSettings: { @@ -212,8 +217,9 @@ AttachmentStorageSettings.helpers({ return this.storageConfig.filesystem?.enabled !== false; case STORAGE_NAME_GRIDFS: return this.storageConfig.gridfs?.enabled !== false; - case STORAGE_NAME_S3: - return this.storageConfig.s3?.enabled === true; + // DISABLED: S3 storage removed due to Node.js compatibility + // case STORAGE_NAME_S3: + // return this.storageConfig.s3?.enabled === true; default: return false; } @@ -228,8 +234,9 @@ AttachmentStorageSettings.helpers({ return this.storageConfig.filesystem; case STORAGE_NAME_GRIDFS: return this.storageConfig.gridfs; - case STORAGE_NAME_S3: - return this.storageConfig.s3; + // DISABLED: S3 storage removed due to Node.js compatibility + // case STORAGE_NAME_S3: + // return this.storageConfig.s3; default: return null; } @@ -274,9 +281,10 @@ if (Meteor.isServer) { gridfs: { enabled: true }, - s3: { - enabled: false - } + // DISABLED: S3 storage removed due to Node.js compatibility + // s3: { + // enabled: false + // } }, uploadSettings: { maxFileSize: process.env.ATTACHMENTS_UPLOAD_MAX_SIZE ? parseInt(process.env.ATTACHMENTS_UPLOAD_MAX_SIZE) : 0, @@ -347,7 +355,7 @@ if (Meteor.isServer) { throw new Meteor.Error('not-authorized', 'Admin access required'); } - if (![STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS, STORAGE_NAME_S3].includes(storageName)) { + if (![STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS].includes(storageName)) { throw new Meteor.Error('invalid-storage', 'Invalid storage backend'); } diff --git a/models/attachments.js b/models/attachments.js index 96de9f79e..2c5af186e 100644 --- a/models/attachments.js +++ b/models/attachments.js @@ -5,10 +5,15 @@ import { isFileValid } from './fileValidation'; import { createBucket } from './lib/grid/createBucket'; import fs from 'fs'; import path from 'path'; -import { AttachmentStoreStrategyFilesystem, AttachmentStoreStrategyGridFs, AttachmentStoreStrategyS3 } from '/models/lib/attachmentStoreStrategy'; -import FileStoreStrategyFactory, {moveToStorage, rename, STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS, STORAGE_NAME_S3} from '/models/lib/fileStoreStrategy'; +import { AttachmentStoreStrategyFilesystem, AttachmentStoreStrategyGridFs } from '/models/lib/attachmentStoreStrategy'; +// DISABLED: S3 storage strategy removed due to Node.js compatibility +// import { AttachmentStoreStrategyS3 } from '/models/lib/attachmentStoreStrategy'; +import FileStoreStrategyFactory, {moveToStorage, rename, STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS} from '/models/lib/fileStoreStrategy'; +// DISABLED: S3 storage removed due to Node.js compatibility +// import { STORAGE_NAME_S3 } from '/models/lib/fileStoreStrategy'; import { getAttachmentWithBackwardCompatibility, getAttachmentsWithBackwardCompatibility } from './lib/attachmentBackwardCompatibility'; import AttachmentStorageSettings from './attachmentStorageSettings'; +import { generateUniversalAttachmentUrl, cleanFileUrl } from '/models/lib/universalUrlGenerator'; let attachmentUploadExternalProgram; let attachmentUploadMimeTypes = []; @@ -40,7 +45,7 @@ if (Meteor.isServer) { } } - storagePath = path.join(process.env.WRITABLE_PATH, 'attachments'); + storagePath = path.join(process.env.WRITABLE_PATH || process.cwd(), 'attachments'); } export const fileStoreStrategyFactory = new FileStoreStrategyFactory(AttachmentStoreStrategyFilesystem, storagePath, AttachmentStoreStrategyGridFs, attachmentBucket); @@ -315,10 +320,45 @@ if (Meteor.isServer) { fs.mkdirSync(storagePath, { recursive: true }); } }); +} - // Add backward compatibility methods - Attachments.getAttachmentWithBackwardCompatibility = getAttachmentWithBackwardCompatibility; - Attachments.getAttachmentsWithBackwardCompatibility = getAttachmentsWithBackwardCompatibility; +// Add backward compatibility methods - available on both client and server +Attachments.getAttachmentWithBackwardCompatibility = getAttachmentWithBackwardCompatibility; +Attachments.getAttachmentsWithBackwardCompatibility = getAttachmentsWithBackwardCompatibility; + +// Override the link method to use universal URLs +if (Meteor.isClient) { + // Override the original FilesCollection link method to use universal URLs + // This must override the ostrio:files method to avoid "Match error: Expected plain object" + const originalLink = Attachments.link; + Attachments.link = function(versionName) { + // Accept both direct calls and collection.helpers style calls + const fileRef = this._id ? this : (versionName && versionName._id ? versionName : this); + const version = (typeof versionName === 'string') ? versionName : 'original'; + + if (fileRef && fileRef._id) { + const url = generateUniversalAttachmentUrl(fileRef._id, version); + if (process.env.DEBUG === 'true') { + console.log('Attachment link generated:', url, 'for ID:', fileRef._id); + } + return url; + } + // Fallback to original if somehow we don't have an ID + return originalLink ? originalLink.call(this, versionName) : ''; + }; + + // Also add as collection helper for document instances + Attachments.collection.helpers({ + link(version) { + // Handle both no-argument and string argument cases + const ver = (typeof version === 'string') ? version : 'original'; + const url = generateUniversalAttachmentUrl(this._id, ver); + if (process.env.DEBUG === 'true') { + console.log('Attachment link (helper) generated:', url, 'for ID:', this._id); + } + return url; + } + }); } export default Attachments; diff --git a/models/avatars.js b/models/avatars.js index 760ef75b4..da3033bc8 100644 --- a/models/avatars.js +++ b/models/avatars.js @@ -8,6 +8,7 @@ import { TAPi18n } from '/imports/i18n'; import fs from 'fs'; import path from 'path'; import FileStoreStrategyFactory, { FileStoreStrategyFilesystem, FileStoreStrategyGridFs, STORAGE_NAME_FILESYSTEM } from '/models/lib/fileStoreStrategy'; +import { generateUniversalAvatarUrl, cleanFileUrl } from '/models/lib/universalUrlGenerator'; const filesize = require('filesize'); @@ -40,10 +41,10 @@ if (Meteor.isServer) { } avatarsBucket = createBucket('avatars'); - storagePath = path.join(process.env.WRITABLE_PATH, 'avatars'); + storagePath = path.join(process.env.WRITABLE_PATH || process.cwd(), 'avatars'); } -const fileStoreStrategyFactory = new FileStoreStrategyFactory(FileStoreStrategyFilesystem, storagePath, FileStoreStrategyGridFs, avatarsBucket); +export const fileStoreStrategyFactory = new FileStoreStrategyFactory(FileStoreStrategyFilesystem, storagePath, FileStoreStrategyGridFs, avatarsBucket); Avatars = new FilesCollection({ debug: false, // Change to `true` for debugging @@ -116,7 +117,9 @@ Avatars = new FilesCollection({ const isValid = Promise.await(isFileValid(fileObj, avatarsUploadMimeTypes, avatarsUploadSize, avatarsUploadExternalProgram)); if (isValid) { - ReactiveCache.getUser(fileObj.userId).setAvatarUrl(`${formatFleURL(fileObj)}?auth=false&brokenIsFine=true`); + // Set avatar URL using universal URL generator (URL-agnostic) + const universalUrl = generateUniversalAvatarUrl(fileObj._id); + ReactiveCache.getUser(fileObj.userId).setAvatarUrl(universalUrl); } else { Avatars.remove(fileObj._id); } @@ -164,4 +167,15 @@ if (Meteor.isServer) { }); } +// Override the link method to use universal URLs +if (Meteor.isClient) { + // Add custom link method to avatar documents + Avatars.collection.helpers({ + link(version = 'original') { + // Use universal URL generator for consistent, URL-agnostic URLs + return generateUniversalAvatarUrl(this._id, version); + } + }); +} + export default Avatars; diff --git a/models/boards.js b/models/boards.js index 55a97c297..569bb5e78 100644 --- a/models/boards.js +++ b/models/boards.js @@ -331,6 +331,19 @@ Boards.attachSchema( optional: true, defaultValue: null, }, + migrationVersion: { + /** + * The migration version of the board structure. + * New boards are created with the latest version and don't need migration. + */ + type: Number, + // eslint-disable-next-line consistent-return + autoValue() { + if (this.isInsert && !this.isSet) { + return 1; // Latest migration version for new boards + } + }, + }, subtasksDefaultListId: { /** @@ -765,6 +778,11 @@ Boards.helpers({ return this.permission === 'public'; }, + hasSharedListsConverted() { + return this.hasSharedListsConverted === true; + }, + + cards() { const ret = ReactiveCache.getCards( { boardId: this._id, archived: false }, @@ -785,8 +803,6 @@ Boards.helpers({ { boardId: this._id, archived: false, - // Get lists for all swimlanes in this board - swimlaneId: { $in: this.swimlanes().map(s => s._id) }, }, { sort: sortKey }, ); @@ -796,8 +812,6 @@ Boards.helpers({ return ReactiveCache.getLists( { boardId: this._id, - // Get lists for all swimlanes in this board - swimlaneId: { $in: this.swimlanes().map(s => s._id) } }, { sort: { sort: 1 } } ); @@ -1125,13 +1139,13 @@ Boards.helpers({ permission: this.permission, members: this.members, color: this.color, - description: TAPi18n.__('default-subtasks-board', { + description: TAPi18n && TAPi18n.i18n ? TAPi18n.__('default-subtasks-board', { board: this.title, - }), + }) : `Default subtasks board for ${this.title}`, }); Swimlanes.insert({ - title: TAPi18n.__('default'), + title: TAPi18n && TAPi18n.i18n ? TAPi18n.__('default') : 'Default', boardId: this.subtasksDefaultBoardId, }); Boards.update(this._id, { @@ -1158,13 +1172,13 @@ Boards.helpers({ permission: this.permission, members: this.members, color: this.color, - description: TAPi18n.__('default-dates-board', { + description: TAPi18n && TAPi18n.i18n ? TAPi18n.__('default-dates-board', { board: this.title, - }), + }) : `Default dates board for ${this.title}`, }); Swimlanes.insert({ - title: TAPi18n.__('default'), + title: TAPi18n && TAPi18n.i18n ? TAPi18n.__('default') : 'Default', boardId: this.dateSettingsDefaultBoardId, }); Boards.update(this._id, { @@ -1186,7 +1200,7 @@ Boards.helpers({ this.subtasksDefaultListId === undefined ) { this.subtasksDefaultListId = Lists.insert({ - title: TAPi18n.__('queue'), + title: TAPi18n && TAPi18n.i18n ? TAPi18n.__('queue') : 'Queue', boardId: this._id, swimlaneId: this.getDefaultSwimline()._id, // Set default swimlane for subtasks list }); @@ -1205,7 +1219,7 @@ Boards.helpers({ this.dateSettingsDefaultListId === undefined ) { this.dateSettingsDefaultListId = Lists.insert({ - title: TAPi18n.__('queue'), + title: TAPi18n && TAPi18n.i18n ? TAPi18n.__('queue') : 'Queue', boardId: this._id, swimlaneId: this.getDefaultSwimline()._id, // Set default swimlane for date settings list }); @@ -1221,11 +1235,20 @@ Boards.helpers({ getDefaultSwimline() { let result = ReactiveCache.getSwimlane({ boardId: this._id }); if (result === undefined) { - Swimlanes.insert({ - title: TAPi18n.__('default'), - boardId: this._id, - }); - result = ReactiveCache.getSwimlane({ boardId: this._id }); + // Check if any swimlane exists for this board to avoid duplicates + const existingSwimlanes = ReactiveCache.getSwimlanes({ boardId: this._id }); + if (existingSwimlanes.length > 0) { + // Use the first existing swimlane + result = existingSwimlanes[0]; + } else { + // Use fallback title if i18n is not available (e.g., during migration) + const title = TAPi18n && TAPi18n.i18n ? TAPi18n.__('default') : 'Default'; + Swimlanes.insert({ + title: title, + boardId: this._id, + }); + result = ReactiveCache.getSwimlane({ boardId: this._id }); + } } return result; }, @@ -1688,9 +1711,10 @@ if (Meteor.isServer) { // All logged in users are allowed to reorder boards by dragging at All Boards page and Public Boards page. Boards.allow({ update(userId, board, fieldNames) { - return _.contains(fieldNames, 'sort'); + return canUpdateBoardSort(userId, board, fieldNames); }, - fetch: [], + // Need members to verify membership in policy + fetch: ['members'], }); // The number of users that have starred this board is managed by trusted code @@ -2186,9 +2210,10 @@ if (Meteor.isServer) { ], permission: req.body.permission || 'private', color: req.body.color || 'belize', + migrationVersion: 1, // Latest version - no migration needed }); const swimlaneId = Swimlanes.insert({ - title: TAPi18n.__('default'), + title: TAPi18n && TAPi18n.i18n ? TAPi18n.__('default') : 'Default', boardId: id, }); JsonRoutes.sendResult(res, { diff --git a/models/cards.js b/models/cards.js index 7dca82b66..a0eaaa8ca 100644 --- a/models/cards.js +++ b/models/cards.js @@ -1,5 +1,24 @@ import { ReactiveCache, ReactiveMiniMongoIndex } from '/imports/reactiveCache'; -import moment from 'moment/min/moment-with-locales'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; import { ALLOWED_COLORS, TYPE_CARD, @@ -8,6 +27,7 @@ import { } from '../config/const'; import Attachments, { fileStoreStrategyFactory } from "./attachments"; import { copyFile } from './lib/fileStoreStrategy.js'; +import PositionHistory from './positionHistory'; Cards = new Mongo.Collection('cards'); @@ -495,18 +515,29 @@ Cards.attachSchema( }), ); +// Centralized update policy for Cards +// Security: deny any direct client updates to 'vote' fields; require membership otherwise +canUpdateCard = function(userId, doc, fields) { + if (!userId) return false; + const fieldNames = fields || []; + // Block direct updates to voting fields; voting must go through Meteor method 'cards.vote' + if (_.some(fieldNames, f => typeof f === 'string' && (f === 'vote' || f.indexOf('vote.') === 0))) { + return false; + } + // Block direct updates to poker fields; poker must go through Meteor methods + if (_.some(fieldNames, f => typeof f === 'string' && (f === 'poker' || f.indexOf('poker.') === 0))) { + return false; + } + return allowIsBoardMember(userId, ReactiveCache.getBoard(doc.boardId)); +}; + Cards.allow({ insert(userId, doc) { return allowIsBoardMember(userId, ReactiveCache.getBoard(doc.boardId)); }, update(userId, doc, fields) { - // Allow board members or logged in users if only vote get's changed - return ( - allowIsBoardMember(userId, ReactiveCache.getBoard(doc.boardId)) || - (_.isEqual(fields, ['vote', 'modifiedAt', 'dateLastActivity']) && - !!userId) - ); + return canUpdateCard(userId, doc, fields); }, remove(userId, doc) { return allowIsBoardMember(userId, ReactiveCache.getBoard(doc.boardId)); @@ -1491,8 +1522,8 @@ Cards.helpers({ expiredVote() { let end = this.getVoteEnd(); if (end) { - end = moment(end); - return end.isBefore(new Date()); + end = new Date(end); + return isBefore(end, new Date()); } return false; }, @@ -1585,8 +1616,8 @@ Cards.helpers({ expiredPoker() { let end = this.getPokerEnd(); if (end) { - end = moment(end); - return end.isBefore(new Date()); + end = new Date(end); + return isBefore(end, new Date()); } return false; }, @@ -1764,11 +1795,11 @@ Cards.helpers({ }, setTitle(title) { - // Sanitize title on client side as well + // Basic client-side validation - server will handle full sanitization let sanitizedTitle = title; if (typeof title === 'string') { - const { sanitizeTitle } = require('../server/lib/inputSanitizer'); - sanitizedTitle = sanitizeTitle(title); + // Basic length check to prevent abuse + sanitizedTitle = title.length > 1000 ? title.substring(0, 1000) : title; if (process.env.DEBUG === 'true' && sanitizedTitle !== title) { console.warn('Client-side sanitized card title:', title, '->', sanitizedTitle); } @@ -3085,6 +3116,273 @@ const addCronJob = _.debounce( if (Meteor.isServer) { Meteor.methods({ + // Secure poker voting: only the caller's userId is modified + 'cards.pokerVote'(cardId, state) { + check(cardId, String); + if (state !== undefined && state !== null) check(state, String); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!board) throw new Meteor.Error('not-found'); + + const isMember = allowIsBoardMember(this.userId, board); + const allowNBM = !!(card.poker && card.poker.allowNonBoardMembers); + if (!(isMember || allowNBM /* && board.permission === 'public' */)) { + throw new Meteor.Error('not-authorized'); + } + + let mod = card.setPoker(this.userId, state); + if (!mod || typeof mod !== 'object') mod = {}; + mod.$set = Object.assign({}, mod.$set, { modifiedAt: new Date(), dateLastActivity: new Date() }); + return Cards.update({ _id: cardId }, mod); + }, + + // Configure planning poker on a card (members only) + 'cards.setPokerQuestion'(cardId, question, allowNonBoardMembers) { + check(cardId, String); + check(question, Boolean); + check(allowNonBoardMembers, Boolean); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $set: { + poker: { + question, + allowNonBoardMembers, + one: [], two: [], three: [], five: [], eight: [], thirteen: [], twenty: [], forty: [], oneHundred: [], unsure: [], + }, + modifiedAt: new Date(), + dateLastActivity: new Date(), + }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + + 'cards.setPokerEnd'(cardId, end) { + check(cardId, String); + check(end, Date); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $set: { 'poker.end': end, modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + + 'cards.unsetPokerEnd'(cardId) { + check(cardId, String); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $unset: { 'poker.end': '' }, + $set: { modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + + 'cards.unsetPoker'(cardId) { + check(cardId, String); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $unset: { poker: '' }, + $set: { modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + + 'cards.setPokerEstimation'(cardId, estimation) { + check(cardId, String); + check(estimation, Number); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $set: { 'poker.estimation': estimation, modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + + 'cards.unsetPokerEstimation'(cardId) { + check(cardId, String); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $unset: { 'poker.estimation': '' }, + $set: { modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + + 'cards.replayPoker'(cardId) { + check(cardId, String); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + // Reset all poker votes arrays + const modifier = { + $set: { + 'poker.one': [], 'poker.two': [], 'poker.three': [], 'poker.five': [], 'poker.eight': [], 'poker.thirteen': [], 'poker.twenty': [], 'poker.forty': [], 'poker.oneHundred': [], 'poker.unsure': [], + modifiedAt: new Date(), + dateLastActivity: new Date(), + }, + $unset: { 'poker.end': '' }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + // Configure voting on a card (members only) + 'cards.setVoteQuestion'(cardId, question, publicVote, allowNonBoardMembers) { + check(cardId, String); + check(question, String); + check(publicVote, Boolean); + check(allowNonBoardMembers, Boolean); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $set: { + vote: { + question, + public: publicVote, + allowNonBoardMembers, + positive: [], + negative: [], + }, + modifiedAt: new Date(), + dateLastActivity: new Date(), + }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + + 'cards.setVoteEnd'(cardId, end) { + check(cardId, String); + check(end, Date); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $set: { 'vote.end': end, modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + + 'cards.unsetVoteEnd'(cardId) { + check(cardId, String); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $unset: { 'vote.end': '' }, + $set: { modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + + 'cards.unsetVote'(cardId) { + check(cardId, String); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!allowIsBoardMember(this.userId, board)) throw new Meteor.Error('not-authorized'); + + const modifier = { + $unset: { vote: '' }, + $set: { modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + return Cards.update({ _id: cardId }, modifier); + }, + // Secure voting: only the caller can set/unset their vote; non-members can vote only when allowed + 'cards.vote'(cardId, forIt) { + check(cardId, String); + // forIt may be true (upvote), false (downvote), or null/undefined (clear) + if (forIt !== undefined && forIt !== null) check(forIt, Boolean); + if (!this.userId) throw new Meteor.Error('not-authorized'); + + const card = ReactiveCache.getCard(cardId) || Cards.findOne(cardId); + if (!card) throw new Meteor.Error('not-found'); + const board = ReactiveCache.getBoard(card.boardId) || Boards.findOne(card.boardId); + if (!board) throw new Meteor.Error('not-found'); + + const isMember = allowIsBoardMember(this.userId, board); + const allowNBM = !!(card.vote && card.vote.allowNonBoardMembers); + if (!(isMember || allowNBM /* && board.permission === 'public' */)) { + throw new Meteor.Error('not-authorized'); + } + + // Only modify the caller's own userId in vote arrays + let modifier; + if (forIt === true) { + modifier = { + $pull: { 'vote.negative': this.userId }, + $addToSet: { 'vote.positive': this.userId }, + $set: { modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + } else if (forIt === false) { + modifier = { + $pull: { 'vote.positive': this.userId }, + $addToSet: { 'vote.negative': this.userId }, + $set: { modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + } else { + // Clear vote + modifier = { + $pull: { 'vote.positive': this.userId, 'vote.negative': this.userId }, + $set: { modifiedAt: new Date(), dateLastActivity: new Date() }, + }; + } + + return Cards.update({ _id: cardId }, modifier); + }, /** copies a card *
  • this method is needed on the server because attachments can only be copied on the server (access to file system) * @param card id to copy @@ -3139,6 +3437,14 @@ if (Meteor.isServer) { Cards.after.insert((userId, doc) => { cardCreation(userId, doc); + + // Track original position for new cards + Meteor.setTimeout(() => { + const card = Cards.findOne(doc._id); + if (card) { + card.trackOriginalPosition(); + } + }, 100); }); // New activity for card (un)archivage Cards.after.update((userId, doc, fieldNames) => { @@ -3192,9 +3498,7 @@ if (Meteor.isServer) { // change list modifiedAt, when user modified the key values in // timingaction array, if it's endAt, put the modifiedAt of list // back to one year ago for sorting purpose - const modifiedAt = moment() - .subtract(1, 'year') - .toISOString(); + const modifiedAt = add(now(), -1, 'year').toISOString(); const boardId = list.boardId; Lists.direct.update( { @@ -3583,8 +3887,8 @@ JsonRoutes.add('GET', '/api/boards/:boardId/cards_count', function( Authentication.checkBoardAccess(req.userId, paramBoardId); if (req.body.title) { - const { sanitizeTitle } = require('../server/lib/inputSanitizer'); - const newTitle = sanitizeTitle(req.body.title); + // Basic client-side validation - server will handle full sanitization + const newTitle = req.body.title.length > 1000 ? req.body.title.substring(0, 1000) : req.body.title; if (process.env.DEBUG === 'true' && newTitle !== req.body.title) { console.warn('Sanitized card title input:', req.body.title, '->', newTitle); @@ -4136,6 +4440,156 @@ JsonRoutes.add('GET', '/api/boards/:boardId/cards_count', function( }); }, ); + + /** + * @operation archive_card + * @summary Archive a card + * + * @description Archive a card + * @param {string} boardId the board ID of the card + * @param {string} listId the list ID of the card + * @param {string} cardId the ID of the card + * @return_type {_id: string, archived: boolean, archivedAt: Date} + */ + JsonRoutes.add( + 'POST', + '/api/boards/:boardId/lists/:listId/cards/:cardId/archive', + function(req, res) { + const paramBoardId = req.params.boardId; + const paramCardId = req.params.cardId; + const paramListId = req.params.listId; + Authentication.checkBoardAccess(req.userId, paramBoardId); + const card = ReactiveCache.getCard({ + _id: paramCardId, + listId: paramListId, + boardId: paramBoardId, + archived: false, + }); + if (!card) { + throw new Meteor.Error(404, 'Card not found'); + } + card.archive(); + JsonRoutes.sendResult(res, { + code: 200, + data: { + _id: paramCardId, + archived: true, + archivedAt: new Date(), + }, + }); + }, + ); + + /** + * @operation unarchive_card + * @summary Unarchive card + * + * @description Unarchive card + * @param {string} boardId the board ID of the card + * @param {string} listId the list ID of the card + * @param {string} cardId the ID of the card + * @return_type {_id: string, archived: boolean} + */ + JsonRoutes.add( + 'POST', + '/api/boards/:boardId/lists/:listId/cards/:cardId/unarchive', + function(req, res) { + const paramBoardId = req.params.boardId; + const paramCardId = req.params.cardId; + const paramListId = req.params.listId; + Authentication.checkBoardAccess(req.userId, paramBoardId); + const card = ReactiveCache.getCard({ + _id: paramCardId, + listId: paramListId, + boardId: paramBoardId, + archived: true, + }); + if (!card) { + throw new Meteor.Error(404, 'Card not found'); + } + card.restore(); + JsonRoutes.sendResult(res, { + code: 200, + data: { + _id: paramCardId, + archived: false, + }, + }); + }, + ); } +// Position history tracking methods +Cards.helpers({ + /** + * Track the original position of this card + */ + trackOriginalPosition() { + const existingHistory = PositionHistory.findOne({ + boardId: this.boardId, + entityType: 'card', + entityId: this._id, + }); + + if (!existingHistory) { + PositionHistory.insert({ + boardId: this.boardId, + entityType: 'card', + entityId: this._id, + originalPosition: { + sort: this.sort, + title: this.title, + }, + originalSwimlaneId: this.swimlaneId || null, + originalListId: this.listId || null, + originalTitle: this.title, + createdAt: new Date(), + updatedAt: new Date(), + }); + } + }, + + /** + * Get the original position history for this card + */ + getOriginalPosition() { + return PositionHistory.findOne({ + boardId: this.boardId, + entityType: 'card', + entityId: this._id, + }); + }, + + /** + * Check if this card has moved from its original position + */ + hasMovedFromOriginalPosition() { + const history = this.getOriginalPosition(); + if (!history) return false; + + const currentSwimlaneId = this.swimlaneId || null; + const currentListId = this.listId || null; + + return history.originalPosition.sort !== this.sort || + history.originalSwimlaneId !== currentSwimlaneId || + history.originalListId !== currentListId; + }, + + /** + * Get a description of the original position + */ + getOriginalPositionDescription() { + const history = this.getOriginalPosition(); + if (!history) return 'No original position data'; + + const swimlaneInfo = history.originalSwimlaneId ? + ` in swimlane ${history.originalSwimlaneId}` : + ' in default swimlane'; + const listInfo = history.originalListId ? + ` in list ${history.originalListId}` : + ''; + return `Original position: ${history.originalPosition.sort || 0}${swimlaneInfo}${listInfo}`; + }, +}); + export default Cards; diff --git a/models/exporter.js b/models/exporter.js index b8fe68ba4..a42dc0f7a 100644 --- a/models/exporter.js +++ b/models/exporter.js @@ -1,7 +1,26 @@ import { ReactiveCache } from '/imports/reactiveCache'; -import moment from 'moment/min/moment-with-locales'; const Papa = require('papaparse'); import { TAPi18n } from '/imports/i18n'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; //const stringify = require('csv-stringify'); @@ -302,15 +321,15 @@ export class Exporter { labels = `${labels + label.name}-${label.color} `; }); currentRow.push(labels.trim()); - currentRow.push(card.startAt ? moment(card.startAt).format() : ' '); - currentRow.push(card.dueAt ? moment(card.dueAt).format() : ' '); - currentRow.push(card.endAt ? moment(card.endAt).format() : ' '); + currentRow.push(card.startAt ? new Date(card.startAt).toISOString() : ' '); + currentRow.push(card.dueAt ? new Date(card.dueAt).toISOString() : ' '); + currentRow.push(card.endAt ? new Date(card.endAt).toISOString() : ' '); currentRow.push(card.isOvertime ? 'true' : 'false'); currentRow.push(card.spentTime); - currentRow.push(card.createdAt ? moment(card.createdAt).format() : ' '); - currentRow.push(card.modifiedAt ? moment(card.modifiedAt).format() : ' '); + currentRow.push(card.createdAt ? new Date(card.createdAt).toISOString() : ' '); + currentRow.push(card.modifiedAt ? new Date(card.modifiedAt).toISOString() : ' '); currentRow.push( - card.dateLastActivity ? moment(card.dateLastActivity).format() : ' ', + card.dateLastActivity ? new Date(card.dateLastActivity).toISOString() : ' ', ); if (card.vote && card.vote.question !== '') { let positiveVoters = ''; @@ -343,7 +362,7 @@ export class Exporter { if (field.value !== null) { if (customFieldMap[field._id].type === 'date') { customFieldValuesToPush[customFieldMap[field._id].position] = - moment(field.value).format(); + new Date(field.value).toISOString(); } else if (customFieldMap[field._id].type === 'dropdown') { const dropdownOptions = result.customFields.find( ({ _id }) => _id === field._id, diff --git a/models/fileValidation.js b/models/fileValidation.js index 349a2572e..bc026a0b2 100644 --- a/models/fileValidation.js +++ b/models/fileValidation.js @@ -12,27 +12,112 @@ if (Meteor.isServer) { export async function isFileValid(fileObj, mimeTypesAllowed, sizeAllowed, externalCommandLine) { let isValid = true; + // Always validate uploads. The previous migration flag disabled validation and enabled XSS. + try { + // Helper: read up to a limit from a file as UTF-8 text + const readTextHead = (filePath, limit = parseInt(process.env.UPLOAD_DANGEROUS_MIME_SCAN_LIMIT || '1048576')) => new Promise((resolve, reject) => { + try { + const stream = fs.createReadStream(filePath, { encoding: 'utf8', highWaterMark: 64 * 1024 }); + let data = ''; + let exceeded = false; + stream.on('data', chunk => { + data += chunk; + if (data.length >= limit) { + exceeded = true; + stream.destroy(); + } + }); + stream.on('error', err => reject(err)); + stream.on('close', () => { + if (exceeded) { + // If file exceeds scan limit, treat as unsafe + resolve({ text: data.slice(0, limit), complete: false }); + } else { + resolve({ text: data, complete: true }); + } + }); + } catch (e) { + reject(e); + } + }); -/* - if (Meteor.settings.public.ostrioFilesMigrationInProgress !== "true") { - if (mimeTypesAllowed.length) { - const mimeTypeResult = await FileType.fromFile(fileObj.path); + // Helper: quick content safety checks for HTML/SVG/XML + const containsJsOrXmlBombs = (text) => { + if (!text) return false; + const t = text.toLowerCase(); + // JavaScript execution vectors + const patterns = [ + / re.test(text))) return true; + // XML entity expansion / DTD based bombs + if (t.includes(' { + // Allow only if content is scanned and clean + const { text, complete } = await readTextHead(filePath); + if (!complete) { + // Too large to confidently scan + return false; + } + // For JS MIME, only allow empty files + if (mime === 'application/javascript' || mime === 'text/javascript') { + return (text.trim().length === 0); + } + return !containsJsOrXmlBombs(text); + }; - isValid = mimeTypesAllowed.includes(mimeType) || mimeTypesAllowed.includes(baseMimeType + '/*') || mimeTypesAllowed.includes('*'); + // Detect MIME type from file content when possible + const mimeTypeResult = await FileType.fromFile(fileObj.path).catch(() => undefined); + const detectedMime = mimeTypeResult?.mime || (fileObj.type || '').toLowerCase(); + const baseMimeType = detectedMime.split('/', 1)[0] || ''; - if (!isValid) { - console.log("Validation of uploaded file failed: file " + fileObj.path + " - mimetype " + mimeType); + // Hard deny-list for obviously dangerous types which can be allowed if content is safe + const dangerousMimes = new Set([ + 'text/html', + 'application/xhtml+xml', + 'image/svg+xml', + 'text/xml', + 'application/xml', + 'application/javascript', + 'text/javascript' + ]); + if (dangerousMimes.has(detectedMime)) { + const allowedByContentScan = await checkDangerousMimeAllowance(detectedMime, fileObj.path, fileObj.size || 0); + if (!allowedByContentScan) { + console.log("Validation of uploaded file failed (dangerous MIME content): file " + fileObj.path + " - mimetype " + detectedMime); + return false; } } + // Optional allow-list: if provided, enforce it using exact or base type match + if (Array.isArray(mimeTypesAllowed) && mimeTypesAllowed.length) { + isValid = mimeTypesAllowed.includes(detectedMime) + || (baseMimeType && mimeTypesAllowed.includes(baseMimeType + '/*')) + || mimeTypesAllowed.includes('*'); + + if (!isValid) { + console.log("Validation of uploaded file failed: file " + fileObj.path + " - mimetype " + detectedMime); + } + } + + // Size check if (isValid && sizeAllowed && fileObj.size > sizeAllowed) { console.log("Validation of uploaded file failed: file " + fileObj.path + " - size " + fileObj.size); isValid = false; } + // External scanner (e.g., antivirus) – expected to delete/quarantine bad files if (isValid && externalCommandLine) { await asyncExec(externalCommandLine.replace("{file}", '"' + fileObj.path + '"')); isValid = fs.existsSync(fileObj.path); @@ -45,8 +130,9 @@ export async function isFileValid(fileObj, mimeTypesAllowed, sizeAllowed, extern if (isValid) { console.debug("Validation of uploaded file successful: file " + fileObj.path); } + } catch (e) { + console.error('Error during file validation:', e); + isValid = false; } -*/ - return isValid; } diff --git a/models/lib/fileStoreStrategy.js b/models/lib/fileStoreStrategy.js index 172945f30..73c278bc9 100644 --- a/models/lib/fileStoreStrategy.js +++ b/models/lib/fileStoreStrategy.js @@ -4,7 +4,8 @@ import { createObjectId } from './grid/createObjectId'; import { httpStreamOutput } from './httpStream.js'; //import {} from './s3/Server-side-file-store.js'; import { ObjectID } from 'bson'; -var Minio = require('minio'); +// DISABLED: Minio support removed due to Node.js compatibility issues +// var Minio = require('minio'); export const STORAGE_NAME_FILESYSTEM = "fs"; export const STORAGE_NAME_GRIDFS = "gridfs"; @@ -18,16 +19,17 @@ export default class FileStoreStrategyFactory { * @param storagePath file storage path * @param classFileStoreStrategyGridFs use this strategy for GridFS storage * @param gridFsBucket use this GridFS Bucket as GridFS Storage - * @param classFileStoreStrategyS3 use this strategy for S3 storage - * @param s3Bucket use this S3 Bucket as S3 Storage + * @param classFileStoreStrategyS3 DISABLED: S3 storage strategy removed due to Node.js compatibility + * @param s3Bucket DISABLED: S3 bucket removed due to Node.js compatibility */ constructor(classFileStoreStrategyFilesystem, storagePath, classFileStoreStrategyGridFs, gridFsBucket, classFileStoreStrategyS3, s3Bucket) { this.classFileStoreStrategyFilesystem = classFileStoreStrategyFilesystem; this.storagePath = storagePath; this.classFileStoreStrategyGridFs = classFileStoreStrategyGridFs; this.gridFsBucket = gridFsBucket; - this.classFileStoreStrategyS3 = classFileStoreStrategyS3; - this.s3Bucket = s3Bucket; + // DISABLED: S3 storage strategy removed due to Node.js compatibility + // this.classFileStoreStrategyS3 = classFileStoreStrategyS3; + // this.s3Bucket = s3Bucket; } /** returns the right FileStoreStrategy @@ -43,7 +45,8 @@ export default class FileStoreStrategyFactory { // uploaded by import, so it's in GridFS (MongoDB) storage = STORAGE_NAME_GRIDFS; } else if (fileObj && fileObj.versions && fileObj.versions[version] && fileObj.versions[version].meta && fileObj.versions[version].meta.pipePath) { - storage = STORAGE_NAME_S3; + // DISABLED: S3 storage removed due to Node.js compatibility - fallback to filesystem + storage = STORAGE_NAME_FILESYSTEM; } else { // newly uploaded, so it's at the filesystem storage = STORAGE_NAME_FILESYSTEM; @@ -51,14 +54,16 @@ export default class FileStoreStrategyFactory { } } let ret; - if ([STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS, STORAGE_NAME_S3].includes(storage)) { + if ([STORAGE_NAME_FILESYSTEM, STORAGE_NAME_GRIDFS].includes(storage)) { if (storage == STORAGE_NAME_FILESYSTEM) { ret = new this.classFileStoreStrategyFilesystem(fileObj, versionName); - } else if (storage == STORAGE_NAME_S3) { - ret = new this.classFileStoreStrategyS3(this.s3Bucket, fileObj, versionName); } else if (storage == STORAGE_NAME_GRIDFS) { ret = new this.classFileStoreStrategyGridFs(this.gridFsBucket, fileObj, versionName); } + } else if (storage == STORAGE_NAME_S3) { + // DISABLED: S3 storage removed due to Node.js compatibility - fallback to filesystem + console.warn('S3 storage is disabled due to Node.js compatibility issues, falling back to filesystem storage'); + ret = new this.classFileStoreStrategyFilesystem(fileObj, versionName); } return ret; } @@ -278,8 +283,52 @@ export class FileStoreStrategyFilesystem extends FileStoreStrategy { * @return the read stream */ getReadStream() { - const ret = fs.createReadStream(this.fileObj.versions[this.versionName].path) - return ret; + const v = this.fileObj.versions[this.versionName] || {}; + const originalPath = v.path || ''; + const normalized = (originalPath || '').replace(/\\/g, '/'); + const isAvatar = normalized.includes('/avatars/') || (this.fileObj.collectionName === 'avatars'); + const baseDir = isAvatar ? 'avatars' : 'attachments'; + const storageRoot = path.join(process.env.WRITABLE_PATH || process.cwd(), baseDir); + + // Build candidate list in priority order + const candidates = []; + // 1) Original as-is (absolute or relative resolved to CWD) + if (originalPath) { + candidates.push(originalPath); + if (!path.isAbsolute(originalPath)) { + candidates.push(path.resolve(process.cwd(), originalPath)); + } + } + // 2) Same basename in storageRoot + const baseName = path.basename(normalized || this.fileObj._id || ''); + if (baseName) { + candidates.push(path.join(storageRoot, baseName)); + } + // 3) Only ObjectID (no extension) in storageRoot + if (this.fileObj && this.fileObj._id) { + candidates.push(path.join(storageRoot, String(this.fileObj._id))); + } + // 4) New strategy naming pattern: -- + if (this.fileObj && this.fileObj._id && this.fileObj.name) { + candidates.push(path.join(storageRoot, `${this.fileObj._id}-${this.versionName}-${this.fileObj.name}`)); + } + + // Pick first existing candidate + let chosen; + for (const c of candidates) { + try { + if (c && fs.existsSync(c)) { + chosen = c; + break; + } + } catch (_) {} + } + + if (!chosen) { + // No existing candidate found + return undefined; + } + return fs.createReadStream(chosen); } /** returns a write stream @@ -323,334 +372,56 @@ export class FileStoreStrategyFilesystem extends FileStoreStrategy { } -/** Strategy to store attachments at S3 */ +/** DISABLED: Strategy to store attachments at S3 - Minio support removed due to Node.js compatibility */ export class FileStoreStrategyS3 extends FileStoreStrategy { - - - /** constructor - * @param s3Bucket use this S3 Bucket - * @param fileObj the current file object - * @param versionName the current version - */ constructor(s3Bucket, fileObj, versionName) { super(fileObj, versionName); this.s3Bucket = s3Bucket; } - /** after successfull upload */ onAfterUpload() { - if (process.env.S3) { - Meteor.settings.s3 = JSON.parse(process.env.S3).s3; - } - - const s3Conf = Meteor.settings.s3 || {}; - const bound = Meteor.bindEnvironment((callback) => { - return callback(); - }); - - /* https://github.com/veliovgroup/Meteor-Files/blob/master/docs/aws-s3-integration.md */ - /* Check settings existence in `Meteor.settings` */ - /* This is the best practice for app security */ - - /* - if (s3Conf && s3Conf.key && s3Conf.secret && s3Conf.bucket && s3Conf.region && s3Conf.sslEnabled) { - // Create a new S3 object - const s3 = new S3({ - secretAccessKey: s3Conf.secret, - accessKeyId: s3Conf.key, - region: s3Conf.region, - sslEnabled: s3Conf.sslEnabled, // optional - httpOptions: { - timeout: 6000, - agent: false - } - }); - } - */ - - if (s3Conf && s3Conf.key && s3Conf.secret && s3Conf.bucket && s3Conf.endPoint && s3Conf.port && s3Conf.sslEnabled) { - // Create a new S3 object - var s3Client = new Minio.Client({ - endPoint: s3Conf.endPoint, - port: s3Conf.port, - useSSL: s3Conf.sslEnabled, - accessKey: s3Conf.key, - secretKey: s3Conf.secret - //region: s3Conf.region, - // sslEnabled: true, // optional - //httpOptions: { - // timeout: 6000, - // agent: false - // - }); - - // Declare the Meteor file collection on the Server - const UserFiles = new FilesCollection({ - debug: false, // Change to `true` for debugging - storagePath: storagePath, - collectionName: 'userFiles', - // Disallow Client to execute remove, use the Meteor.method - allowClientCode: false, - - // Start moving files to AWS:S3 - // after fully received by the Meteor server - onAfterUpload(fileRef) { - // Run through each of the uploaded file - _.each(fileRef.versions, (vRef, version) => { - // We use Random.id() instead of real file's _id - // to secure files from reverse engineering on the AWS client - const filePath = 'files/' + (Random.id()) + '-' + version + '.' + fileRef.extension; - - // Create the AWS:S3 object. - // Feel free to change the storage class from, see the documentation, - // `STANDARD_IA` is the best deal for low access files. - // Key is the file name we are creating on AWS:S3, so it will be like files/XXXXXXXXXXXXXXXXX-original.XXXX - // Body is the file stream we are sending to AWS - - const fileObj = this.fileObj; - const versionName = this.versionName; - const metadata = { ...fileObj.meta, versionName, fileId: fileObj._id }; - - s3Client.putObject({ - // ServerSideEncryption: 'AES256', // Optional - //StorageClass: 'STANDARD', - Bucket: s3Conf.bucket, - Key: filePath, - Body: fs.createReadStream(vRef.path), - metadata, - ContentType: vRef.type, - }, (error) => { - bound(() => { - if (error) { - console.error(error); - } else { - // Update FilesCollection with link to the file at AWS - const upd = { $set: {} }; - upd['$set']['versions.' + version + '.meta.pipePath'] = filePath; - - this.collection.update({ - _id: fileRef._id - }, upd, (updError) => { - if (updError) { - console.error(updError); - } else { - // Unlink original files from FS after successful upload to AWS:S3 - this.unlink(this.collection.findOne(fileRef._id), version); - } - }); - } - }); - }); - }); - }, - }); - } + console.warn('S3 storage is disabled due to Node.js compatibility issues'); } - // Intercept access to the file - // And redirect request to AWS:S3 interceptDownload(http, fileRef, version) { - let path; - - if (fileRef && fileRef.versions && fileRef.versions[version] && fileRef.versions[version].meta && fileRef.versions[version].meta.pipePath) { - path = fileRef.versions[version].meta.pipePath; - } - - if (path) { - // If file is successfully moved to AWS:S3 - // We will pipe request to AWS:S3 - // So, original link will stay always secure - - // To force ?play and ?download parameters - // and to keep original file name, content-type, - // content-disposition, chunked "streaming" and cache-control - // we're using low-level .serve() method - const opts = { - Bucket: s3Conf.bucket, - Key: path - }; - - if (http.request.headers.range) { - const vRef = fileRef.versions[version]; - let range = _.clone(http.request.headers.range); - const array = range.split(/bytes=([0-9]*)-([0-9]*)/); - const start = parseInt(array[1]); - let end = parseInt(array[2]); - if (isNaN(end)) { - // Request data from AWS:S3 by small chunks - end = (start + this.chunkSize) - 1; - if (end >= vRef.size) { - end = vRef.size - 1; - } - } - opts.Range = `bytes=${start}-${end}`; - http.request.headers.range = `bytes=${start}-${end}`; - } - - const fileColl = this; - s3Client.getObject(opts, function (error) { - if (error) { - console.error(error); - if (!http.response.finished) { - http.response.end(); - } - } else { - if (http.request.headers.range && this.httpResponse.headers['content-range']) { - // Set proper range header in according to what is returned from AWS:S3 - http.request.headers.range = this.httpResponse.headers['content-range'].split('/')[0].replace('bytes ', 'bytes='); - } - - const dataStream = new stream.PassThrough(); - fileColl.serve(http, fileRef, fileRef.versions[version], version, dataStream); - dataStream.end(this.data.Body); - } - }); - return true; - } - // While file is not yet uploaded to AWS:S3 - // It will be served file from FS - return false; + console.warn('S3 storage is disabled due to Node.js compatibility issues'); + http.response.writeHead(503, { 'Content-Type': 'text/plain' }); + http.response.end('S3 storage is disabled'); } - - /** after file remove */ - onAfterRemove() { - - if (process.env.S3) { - Meteor.settings.s3 = JSON.parse(process.env.S3).s3; - } - - const s3Conf = Meteor.settings.s3 || {}; - const bound = Meteor.bindEnvironment((callback) => { - return callback(); - }); - - if (s3Conf && s3Conf.key && s3Conf.secret && s3Conf.bucket && s3Conf.endPoint && s3Conf.port && s3Conf.sslEnabled) { - // Create a new S3 object - var s3Client = new Minio.Client({ - endPoint: s3Conf.endPoint, - port: s3Conf.port, - useSSL: s3Conf.sslEnabled, - accessKey: s3Conf.key, - secretKey: s3Conf.secret - }); - } - - this.unlink(); - super.onAfterRemove(); - // Intercept FilesCollection's remove method to remove file from AWS:S3 - const _origRemove = UserFiles.remove; - UserFiles.remove = function (selector, callback) { - const cursor = this.collection.find(selector); - cursor.forEach((fileRef) => { - _.each(fileRef.versions, (vRef) => { - if (vRef && vRef.meta && vRef.meta.pipePath) { - // Remove the object from AWS:S3 first, then we will call the original FilesCollection remove - s3Client.deleteObject({ - Bucket: s3Conf.bucket, - Key: vRef.meta.pipePath, - }, (error) => { - bound(() => { - if (error) { - console.error(error); - } - }); - }); - } - }); - }); - // Remove original file from database - _origRemove.call(this, selector, callback); - }; -} - - /** returns a read stream - * @return the read stream - */ getReadStream() { - const s3Id = this.getS3ObjectId(); - let ret; - if (s3Id) { - ret = this.s3Bucket.openDownloadStream(s3Id); - } - return ret; + throw new Error('S3 storage is disabled due to Node.js compatibility issues'); } - /** returns a write stream - * @param filePath if set, use this path - * @return the write stream - */ getWriteStream(filePath) { - const fileObj = this.fileObj; - const versionName = this.versionName; - const metadata = { ...fileObj.meta, versionName, fileId: fileObj._id }; - const ret = this.s3Bucket.openUploadStream(this.fileObj.name, { - contentType: fileObj.type || 'binary/octet-stream', - metadata, - }); - return ret; + throw new Error('S3 storage is disabled due to Node.js compatibility issues'); } - /** writing finished - * @param finishedData the data of the write stream finish event - */ - writeStreamFinished(finishedData) { - const s3FileIdName = this.getS3FileIdName(); - Attachments.update({ _id: this.fileObj._id }, { $set: { [s3FileIdName]: finishedData._id.toHexString(), } }); + getPath() { + throw new Error('S3 storage is disabled due to Node.js compatibility issues'); } - /** remove the file */ - unlink() { - const s3Id = this.gets3ObjectId(); - if (s3Id) { - this.s3Bucket.delete(s3Id, err => { - if (err) { - console.error("error on S3 bucket.delete: ", err); - } - }); - } - - const s3FileIdName = this.getS3FileIdName(); - Attachments.update({ _id: this.fileObj._id }, { $unset: { [s3FileIdName]: 1 } }); + getNewPath(storagePath) { + throw new Error('S3 storage is disabled due to Node.js compatibility issues'); } - /** return the storage name - * @return the storage name - */ getStorageName() { return STORAGE_NAME_S3; } - /** returns the GridFS Object-Id - * @return the GridFS Object-Id - */ - getS3ObjectId() { - let ret; - const s3FileId = this.s3FileId(); - if (s3FileId) { - ret = createObjectId({ s3FileId }); - } - return ret; + writeStreamFinished(finishedData) { + console.warn('S3 storage is disabled due to Node.js compatibility issues'); } - /** returns the S3 Object-Id - * @return the S3 Object-Id - */ - getS3FileId() { - const ret = (this.fileObj.versions[this.versionName].meta || {}) - .s3FileId; - return ret; + unlink() { + console.warn('S3 storage is disabled due to Node.js compatibility issues'); } - /** returns the property name of s3FileId - * @return the property name of s3FileId - */ getS3FileIdName() { const ret = `versions.${this.versionName}.meta.s3FileId`; return ret; } -}; - +} /** move the fileObj to another storage @@ -761,4 +532,4 @@ export const rename = function(fileObj, newName, fileStoreStrategyFactory) { [`versions.${versionName}.path`]: newFilePath, } }); }); -}; +}; \ No newline at end of file diff --git a/models/lib/meteorMongoIntegration.js b/models/lib/meteorMongoIntegration.js index 16e62d53a..43a6af389 100644 --- a/models/lib/meteorMongoIntegration.js +++ b/models/lib/meteorMongoIntegration.js @@ -50,7 +50,7 @@ class MeteorMongoIntegration { this.overrideMongoCollection(); this.isInitialized = true; - console.log('Meteor MongoDB Integration initialized successfully'); + // Meteor MongoDB Integration initialized successfully (status available in Admin Panel) } /** @@ -296,11 +296,8 @@ export { meteorMongoIntegration, MeteorMongoIntegration }; // Auto-initialize if MONGO_URL is available if (Meteor.isServer && process.env.MONGO_URL) { - console.log('Auto-initializing Meteor MongoDB Integration with MONGO_URL'); + // Auto-initializing Meteor MongoDB Integration with MONGO_URL (status available in Admin Panel) meteorMongoIntegration.initialize(process.env.MONGO_URL); } -// Log initialization -if (Meteor.isServer) { - console.log('Meteor MongoDB Integration module loaded'); -} +// Meteor MongoDB Integration module loaded (status available in Admin Panel) diff --git a/models/lib/mongodbConnectionManager.js b/models/lib/mongodbConnectionManager.js index a10701e8f..2c37ac513 100644 --- a/models/lib/mongodbConnectionManager.js +++ b/models/lib/mongodbConnectionManager.js @@ -288,7 +288,4 @@ const mongodbConnectionManager = new MongoDBConnectionManager(); // Export for use in other modules export { mongodbConnectionManager, MongoDBConnectionManager }; -// Log initialization -if (Meteor.isServer) { - console.log('MongoDB Connection Manager initialized'); -} +// MongoDB Connection Manager initialized (status available in Admin Panel) diff --git a/models/lib/mongodbDriverManager.js b/models/lib/mongodbDriverManager.js index 24f38d9b0..19d71329a 100644 --- a/models/lib/mongodbDriverManager.js +++ b/models/lib/mongodbDriverManager.js @@ -270,8 +270,4 @@ const mongodbDriverManager = new MongoDBDriverManager(); // Export for use in other modules export { mongodbDriverManager, MongoDBDriverManager }; -// Log initialization -if (Meteor.isServer) { - console.log('MongoDB Driver Manager initialized'); - console.log(`Supported MongoDB versions: ${mongodbDriverManager.getSupportedVersions().join(', ')}`); -} +// MongoDB Driver Manager initialized (status available in Admin Panel) diff --git a/models/lib/universalUrlGenerator.js b/models/lib/universalUrlGenerator.js new file mode 100644 index 000000000..16a8d0030 --- /dev/null +++ b/models/lib/universalUrlGenerator.js @@ -0,0 +1,194 @@ +/** + * Universal URL Generator + * Generates file URLs that work regardless of ROOT_URL and PORT settings + * Ensures all attachments and avatars are always visible + */ + +import { Meteor } from 'meteor/meteor'; + +/** + * Generate a universal file URL that works regardless of ROOT_URL and PORT + * @param {string} fileId - The file ID + * @param {string} type - The file type ('attachment' or 'avatar') + * @param {string} version - The file version (default: 'original') + * @returns {string} - Universal file URL + */ +export function generateUniversalFileUrl(fileId, type, version = 'original') { + if (!fileId) { + return ''; + } + + // Always use relative URLs to avoid ROOT_URL and PORT dependencies + if (type === 'attachment') { + return `/cdn/storage/attachments/${fileId}`; + } else if (type === 'avatar') { + return `/cdn/storage/avatars/${fileId}`; + } + + return ''; +} + +/** + * Generate a universal attachment URL + * @param {string} attachmentId - The attachment ID + * @param {string} version - The file version (default: 'original') + * @returns {string} - Universal attachment URL + */ +export function generateUniversalAttachmentUrl(attachmentId, version = 'original') { + return generateUniversalFileUrl(attachmentId, 'attachment', version); +} + +/** + * Generate a universal avatar URL + * @param {string} avatarId - The avatar ID + * @param {string} version - The file version (default: 'original') + * @returns {string} - Universal avatar URL + */ +export function generateUniversalAvatarUrl(avatarId, version = 'original') { + return generateUniversalFileUrl(avatarId, 'avatar', version); +} + +/** + * Clean and normalize a file URL to ensure it's universal + * @param {string} url - The URL to clean + * @param {string} type - The file type ('attachment' or 'avatar') + * @returns {string} - Cleaned universal URL + */ +export function cleanFileUrl(url, type) { + if (!url) { + return ''; + } + + // Remove any domain, port, or protocol from the URL + let cleanUrl = url; + + // Remove protocol and domain + cleanUrl = cleanUrl.replace(/^https?:\/\/[^\/]+/, ''); + + // Remove ROOT_URL pathname if present + if (Meteor.isServer && process.env.ROOT_URL) { + try { + const rootUrl = new URL(process.env.ROOT_URL); + if (rootUrl.pathname && rootUrl.pathname !== '/') { + cleanUrl = cleanUrl.replace(rootUrl.pathname, ''); + } + } catch (e) { + // Ignore URL parsing errors + } + } + + // Normalize path separators + cleanUrl = cleanUrl.replace(/\/+/g, '/'); + + // Ensure URL starts with / + if (!cleanUrl.startsWith('/')) { + cleanUrl = '/' + cleanUrl; + } + + // Convert old CollectionFS URLs to new format + if (type === 'attachment') { + cleanUrl = cleanUrl.replace('/cfs/files/attachments/', '/cdn/storage/attachments/'); + } else if (type === 'avatar') { + cleanUrl = cleanUrl.replace('/cfs/files/avatars/', '/cdn/storage/avatars/'); + } + + // Remove any query parameters that might cause issues + cleanUrl = cleanUrl.split('?')[0]; + cleanUrl = cleanUrl.split('#')[0]; + + return cleanUrl; +} + +/** + * Check if a URL is a universal file URL + * @param {string} url - The URL to check + * @param {string} type - The file type ('attachment' or 'avatar') + * @returns {boolean} - True if it's a universal file URL + */ +export function isUniversalFileUrl(url, type) { + if (!url) { + return false; + } + + if (type === 'attachment') { + return url.includes('/cdn/storage/attachments/') || url.includes('/cfs/files/attachments/'); + } else if (type === 'avatar') { + return url.includes('/cdn/storage/avatars/') || url.includes('/cfs/files/avatars/'); + } + + return false; +} + +/** + * Extract file ID from a universal file URL + * @param {string} url - The URL to extract from + * @param {string} type - The file type ('attachment' or 'avatar') + * @returns {string|null} - The file ID or null if not found + */ +export function extractFileIdFromUrl(url, type) { + if (!url) { + return null; + } + + let pattern; + if (type === 'attachment') { + pattern = /\/(?:cdn\/storage\/attachments|cfs\/files\/attachments)\/([^\/\?#]+)/; + } else if (type === 'avatar') { + pattern = /\/(?:cdn\/storage\/avatars|cfs\/files\/avatars)\/([^\/\?#]+)/; + } else { + return null; + } + + const match = url.match(pattern); + return match ? match[1] : null; +} + +/** + * Generate a fallback URL for when the primary URL fails + * @param {string} fileId - The file ID + * @param {string} type - The file type ('attachment' or 'avatar') + * @returns {string} - Fallback URL + */ +export function generateFallbackUrl(fileId, type) { + if (!fileId) { + return ''; + } + + // Try alternative route patterns + if (type === 'attachment') { + return `/attachments/${fileId}`; + } else if (type === 'avatar') { + return `/avatars/${fileId}`; + } + + return ''; +} + +/** + * Get all possible URLs for a file (for redundancy) + * @param {string} fileId - The file ID + * @param {string} type - The file type ('attachment' or 'avatar') + * @returns {Array} - Array of possible URLs + */ +export function getAllPossibleUrls(fileId, type) { + if (!fileId) { + return []; + } + + const urls = []; + + // Primary URL + urls.push(generateUniversalFileUrl(fileId, type)); + + // Fallback URL + urls.push(generateFallbackUrl(fileId, type)); + + // Legacy URLs for backward compatibility + if (type === 'attachment') { + urls.push(`/cfs/files/attachments/${fileId}`); + } else if (type === 'avatar') { + urls.push(`/cfs/files/avatars/${fileId}`); + } + + return urls.filter(url => url); // Remove empty URLs +} diff --git a/models/lists.js b/models/lists.js index ca9808e68..3c5087d03 100644 --- a/models/lists.js +++ b/models/lists.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { ALLOWED_COLORS } from '/config/const'; +import PositionHistory from './positionHistory'; Lists = new Mongo.Collection('lists'); @@ -50,10 +51,11 @@ Lists.attachSchema( }, swimlaneId: { /** - * the swimlane associated to this list. Required for per-swimlane list titles + * the swimlane associated to this list. Optional for backward compatibility */ type: String, - // Remove defaultValue to make it required + optional: true, + defaultValue: '', }, createdAt: { /** @@ -313,13 +315,10 @@ Lists.helpers({ Lists.mutations({ rename(title) { - // Sanitize title on client side as well + // Basic client-side validation - server will handle full sanitization if (typeof title === 'string') { - const { sanitizeTitle } = require('../server/lib/inputSanitizer'); - const sanitizedTitle = sanitizeTitle(title); - if (process.env.DEBUG === 'true' && sanitizedTitle !== title) { - console.warn('Client-side sanitized list title:', title, '->', sanitizedTitle); - } + // Basic length check to prevent abuse + const sanitizedTitle = title.length > 1000 ? title.substring(0, 1000) : title; return { $set: { title: sanitizedTitle } }; } return { $set: { title } }; @@ -455,6 +454,14 @@ if (Meteor.isServer) { // list is deleted title: doc.title, }); + + // Track original position for new lists + Meteor.setTimeout(() => { + const list = Lists.findOne(doc._id); + if (list) { + list.trackOriginalPosition(); + } + }, 100); }); Lists.before.remove((userId, doc) => { @@ -653,8 +660,8 @@ if (Meteor.isServer) { // Update title if provided if (req.body.title) { - const { sanitizeTitle } = require('../server/lib/inputSanitizer'); - const newTitle = sanitizeTitle(req.body.title); + // Basic client-side validation - server will handle full sanitization + const newTitle = req.body.title.length > 1000 ? req.body.title.substring(0, 1000) : req.body.title; if (process.env.DEBUG === 'true' && newTitle !== req.body.title) { console.warn('Sanitized list title input:', req.body.title, '->', newTitle); @@ -807,4 +814,77 @@ if (Meteor.isServer) { }); } +// Position history tracking methods +Lists.helpers({ + /** + * Track the original position of this list + */ + trackOriginalPosition() { + const existingHistory = PositionHistory.findOne({ + boardId: this.boardId, + entityType: 'list', + entityId: this._id, + }); + + if (!existingHistory) { + PositionHistory.insert({ + boardId: this.boardId, + entityType: 'list', + entityId: this._id, + originalPosition: { + sort: this.sort, + title: this.title, + }, + originalSwimlaneId: this.swimlaneId || null, + originalTitle: this.title, + createdAt: new Date(), + updatedAt: new Date(), + }); + } + }, + + /** + * Get the original position history for this list + */ + getOriginalPosition() { + return PositionHistory.findOne({ + boardId: this.boardId, + entityType: 'list', + entityId: this._id, + }); + }, + + /** + * Check if this list has moved from its original position + */ + hasMovedFromOriginalPosition() { + const history = this.getOriginalPosition(); + if (!history) return false; + + const currentSwimlaneId = this.swimlaneId || null; + return history.originalPosition.sort !== this.sort || + history.originalSwimlaneId !== currentSwimlaneId; + }, + + /** + * Get a description of the original position + */ + getOriginalPositionDescription() { + const history = this.getOriginalPosition(); + if (!history) return 'No original position data'; + + const swimlaneInfo = history.originalSwimlaneId ? + ` in swimlane ${history.originalSwimlaneId}` : + ' in default swimlane'; + return `Original position: ${history.originalPosition.sort || 0}${swimlaneInfo}`; + }, + + /** + * Get the effective swimlane ID (for backward compatibility) + */ + getEffectiveSwimlaneId() { + return this.swimlaneId || null; + }, +}); + export default Lists; diff --git a/models/positionHistory.js b/models/positionHistory.js new file mode 100644 index 000000000..a70b9fbab --- /dev/null +++ b/models/positionHistory.js @@ -0,0 +1,170 @@ +import { ReactiveCache } from '/imports/reactiveCache'; + +/** + * PositionHistory collection to track original positions of swimlanes, lists, and cards + * before the list naming feature was added in commit 719ef87efceacfe91461a8eeca7cf74d11f4cc0a + */ +PositionHistory = new Mongo.Collection('positionHistory'); + +PositionHistory.attachSchema( + new SimpleSchema({ + boardId: { + /** + * The board ID this position history belongs to + */ + type: String, + }, + entityType: { + /** + * Type of entity: 'swimlane', 'list', or 'card' + */ + type: String, + allowedValues: ['swimlane', 'list', 'card'], + }, + entityId: { + /** + * The ID of the entity (swimlane, list, or card) + */ + type: String, + }, + originalPosition: { + /** + * The original position data before any changes + */ + type: Object, + blackbox: true, + }, + originalSwimlaneId: { + /** + * The original swimlane ID (for lists and cards) + */ + type: String, + optional: true, + }, + originalListId: { + /** + * The original list ID (for cards) + */ + type: String, + optional: true, + }, + originalTitle: { + /** + * The original title before any changes + */ + type: String, + optional: true, + }, + createdAt: { + /** + * When this position history was created + */ + type: Date, + autoValue() { + if (this.isInsert) { + return new Date(); + } else if (this.isUpsert) { + return { $setOnInsert: new Date() }; + } else { + this.unset(); + } + }, + }, + updatedAt: { + /** + * When this position history was last updated + */ + type: Date, + autoValue() { + if (this.isUpdate || this.isUpsert || this.isInsert) { + return new Date(); + } else { + this.unset(); + } + }, + }, + }), +); + +PositionHistory.helpers({ + /** + * Get the original position data + */ + getOriginalPosition() { + return this.originalPosition; + }, + + /** + * Get the original title + */ + getOriginalTitle() { + return this.originalTitle || ''; + }, + + /** + * Get the original swimlane ID + */ + getOriginalSwimlaneId() { + return this.originalSwimlaneId; + }, + + /** + * Get the original list ID + */ + getOriginalListId() { + return this.originalListId; + }, + + /** + * Check if this entity has been moved from its original position + */ + hasMoved() { + if (this.entityType === 'swimlane') { + return this.originalPosition.sort !== undefined; + } else if (this.entityType === 'list') { + return this.originalPosition.sort !== undefined || + this.originalSwimlaneId !== this.entityId; + } else if (this.entityType === 'card') { + return this.originalPosition.sort !== undefined || + this.originalSwimlaneId !== this.entityId || + this.originalListId !== this.entityId; + } + return false; + }, + + /** + * Get a human-readable description of the original position + */ + getOriginalPositionDescription() { + const position = this.originalPosition; + if (!position) return 'Unknown position'; + + if (this.entityType === 'swimlane') { + return `Original position: ${position.sort || 0}`; + } else if (this.entityType === 'list') { + const swimlaneInfo = this.originalSwimlaneId ? + ` in swimlane ${this.originalSwimlaneId}` : + ' in default swimlane'; + return `Original position: ${position.sort || 0}${swimlaneInfo}`; + } else if (this.entityType === 'card') { + const swimlaneInfo = this.originalSwimlaneId ? + ` in swimlane ${this.originalSwimlaneId}` : + ' in default swimlane'; + const listInfo = this.originalListId ? + ` in list ${this.originalListId}` : + ''; + return `Original position: ${position.sort || 0}${swimlaneInfo}${listInfo}`; + } + return 'Unknown position'; + } +}); + +if (Meteor.isServer) { + Meteor.startup(() => { + PositionHistory._collection.createIndex({ boardId: 1, entityType: 1, entityId: 1 }); + PositionHistory._collection.createIndex({ boardId: 1, entityType: 1 }); + PositionHistory._collection.createIndex({ createdAt: -1 }); + }); +} + +export default PositionHistory; diff --git a/models/server/ExporterCardPDF.js b/models/server/ExporterCardPDF.js index f3fde0f85..37551e6cb 100644 --- a/models/server/ExporterCardPDF.js +++ b/models/server/ExporterCardPDF.js @@ -1,6 +1,26 @@ import { ReactiveCache } from '/imports/reactiveCache'; // exporter maybe is broken since Gridfs introduced, add fs and path import { createWorkbook } from './createWorkbook'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; class ExporterCardPDF { constructor(boardId) { @@ -353,8 +373,8 @@ class ExporterCardPDF { //add data +8 hours function addTZhours(jdate) { const curdate = new Date(jdate); - const checkCorrectDate = moment(curdate); - if (checkCorrectDate.isValid()) { + const checkCorrectDate = new Date(curdate); + if (isValidDate(checkCorrectDate)) { return curdate; } else { return ' '; diff --git a/models/server/ExporterExcel.js b/models/server/ExporterExcel.js index 72120dddb..e9775baff 100644 --- a/models/server/ExporterExcel.js +++ b/models/server/ExporterExcel.js @@ -1,7 +1,26 @@ import { ReactiveCache } from '/imports/reactiveCache'; -import moment from 'moment/min/moment-with-locales'; import { TAPi18n } from '/imports/i18n'; import { createWorkbook } from './createWorkbook'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; // exporter maybe is broken since Gridfs introduced, add fs and path @@ -379,8 +398,8 @@ class ExporterExcel { function addTZhours(jdate) { if (!jdate) { return ' '; } const curdate = new Date(jdate); - const checkCorrectDate = moment(curdate); - if (checkCorrectDate.isValid()) { + const checkCorrectDate = new Date(curdate); + if (isValidDate(checkCorrectDate)) { return curdate; } else { return ' '; diff --git a/models/swimlanes.js b/models/swimlanes.js index 2636b274a..659111d04 100644 --- a/models/swimlanes.js +++ b/models/swimlanes.js @@ -1,5 +1,6 @@ import { ReactiveCache } from '/imports/reactiveCache'; import { ALLOWED_COLORS } from '/config/const'; +import PositionHistory from './positionHistory'; Swimlanes = new Mongo.Collection('swimlanes'); @@ -210,21 +211,20 @@ Swimlanes.helpers({ return this.draggableLists(); }, newestLists() { - // sorted lists from newest to the oldest, by its creation date or its cards' last modification date + // Revert to shared lists across swimlanes: filter by board only return ReactiveCache.getLists( { boardId: this.boardId, - swimlaneId: this._id, // Only get lists that belong to this specific swimlane archived: false, }, { sort: { modifiedAt: -1 } }, ); }, draggableLists() { + // Revert to shared lists across swimlanes: filter by board only return ReactiveCache.getLists( { boardId: this.boardId, - swimlaneId: this._id, // Only get lists that belong to this specific swimlane //archived: false, }, { sort: ['sort'] }, @@ -232,7 +232,12 @@ Swimlanes.helpers({ }, myLists() { - return ReactiveCache.getLists({ swimlaneId: this._id }); + // Return per-swimlane lists: provide lists specific to this swimlane + return ReactiveCache.getLists({ + boardId: this.boardId, + swimlaneId: this._id, + archived: false + }); }, allCards() { @@ -354,6 +359,14 @@ if (Meteor.isServer) { boardId: doc.boardId, swimlaneId: doc._id, }); + + // Track original position for new swimlanes + Meteor.setTimeout(() => { + const swimlane = Swimlanes.findOne(doc._id); + if (swimlane) { + swimlane.trackOriginalPosition(); + } + }, 100); }); Swimlanes.before.remove(function(userId, doc) { @@ -602,4 +615,64 @@ if (Meteor.isServer) { ); } +// Position history tracking methods +Swimlanes.helpers({ + /** + * Track the original position of this swimlane + */ + trackOriginalPosition() { + const existingHistory = PositionHistory.findOne({ + boardId: this.boardId, + entityType: 'swimlane', + entityId: this._id, + }); + + if (!existingHistory) { + PositionHistory.insert({ + boardId: this.boardId, + entityType: 'swimlane', + entityId: this._id, + originalPosition: { + sort: this.sort, + title: this.title, + }, + originalTitle: this.title, + createdAt: new Date(), + updatedAt: new Date(), + }); + } + }, + + /** + * Get the original position history for this swimlane + */ + getOriginalPosition() { + return PositionHistory.findOne({ + boardId: this.boardId, + entityType: 'swimlane', + entityId: this._id, + }); + }, + + /** + * Check if this swimlane has moved from its original position + */ + hasMovedFromOriginalPosition() { + const history = this.getOriginalPosition(); + if (!history) return false; + + return history.originalPosition.sort !== this.sort; + }, + + /** + * Get a description of the original position + */ + getOriginalPositionDescription() { + const history = this.getOriginalPosition(); + if (!history) return 'No original position data'; + + return `Original position: ${history.originalPosition.sort || 0}`; + }, +}); + export default Swimlanes; diff --git a/models/trelloCreator.js b/models/trelloCreator.js index 2d445bc46..5dde821c0 100644 --- a/models/trelloCreator.js +++ b/models/trelloCreator.js @@ -1,10 +1,29 @@ import { ReactiveCache } from '/imports/reactiveCache'; -import moment from 'moment/min/moment-with-locales'; import { TAPi18n } from '/imports/i18n'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; const DateString = Match.Where(function(dateAsString) { check(dateAsString, String); - return moment(dateAsString, moment.ISO_8601).isValid(); + return isValidDate(new Date(dateAsString)); }); export class TrelloCreator { diff --git a/models/users.js b/models/users.js index 0e2ff1db7..3885638d1 100644 --- a/models/users.js +++ b/models/users.js @@ -1,4 +1,5 @@ import { ReactiveCache, ReactiveMiniMongoIndex } from '/imports/reactiveCache'; +import { Random } from 'meteor/random'; import { SyncedCron } from 'meteor/percolate:synced-cron'; import { TAPi18n } from '/imports/i18n'; import ImpersonatedUsers from './impersonatedUsers'; @@ -200,6 +201,29 @@ Users.attachSchema( type: String, optional: true, }, + 'profile.boardWorkspacesTree': { + /** + * Per-user spaces tree for All Boards page + */ + type: Array, + optional: true, + }, + 'profile.boardWorkspacesTree.$': { + /** + * Space node: { id: String, name: String, children: Array } + */ + type: Object, + blackbox: true, + optional: true, + }, + 'profile.boardWorkspaceAssignments': { + /** + * Per-user map of boardId -> spaceId + */ + type: Object, + optional: true, + blackbox: true, + }, 'profile.invitedBoards': { /** * board IDs the user has been invited to @@ -465,6 +489,15 @@ Users.attachSchema( type: Boolean, defaultValue: true, }, + 'profile.dateFormat': { + /** + * User-specified date format for displaying dates (includes time HH:MM). + */ + type: String, + optional: true, + allowedValues: ['YYYY-MM-DD', 'DD-MM-YYYY', 'MM-DD-YYYY'], + defaultValue: 'YYYY-MM-DD', + }, 'profile.zoomLevel': { /** * User-specified zoom level for board view (1.0 = 100%, 1.5 = 150%, etc.) @@ -560,15 +593,41 @@ Users.attachSchema( }), ); +// Security helpers for user updates +export const USER_UPDATE_ALLOWED_EXACT = ['username']; +export const USER_UPDATE_ALLOWED_PREFIXES = ['profile.']; +export const USER_UPDATE_FORBIDDEN_PREFIXES = [ + 'services', + 'emails', + 'roles', + 'isAdmin', + 'createdThroughApi', + 'orgs', + 'teams', + 'loginDisabled', + 'authenticationMethod', + 'sessionData', +]; + +export function isUserUpdateAllowed(fields) { + return fields.every((f) => + USER_UPDATE_ALLOWED_EXACT.includes(f) || USER_UPDATE_ALLOWED_PREFIXES.some((p) => f.startsWith(p)) + ); +} + +export function hasForbiddenUserUpdateField(fields) { + return fields.some((f) => USER_UPDATE_FORBIDDEN_PREFIXES.some((p) => f === p || f.startsWith(p + '.'))); +} + Users.allow({ - update(userId, doc) { - const user = ReactiveCache.getUser(userId) || ReactiveCache.getCurrentUser(); - if (user?.isAdmin) - return true; - if (!user) { - return false; - } - return doc._id === userId; + update(userId, doc, fields /*, modifier */) { + // Only the owner can update, and only for allowed fields + if (!userId || doc._id !== userId) return false; + if (!Array.isArray(fields) || fields.length === 0) return false; + // Disallow if any forbidden field present + if (hasForbiddenUserUpdateField(fields)) return false; + // Allow only username and profile.* + return isUserUpdateAllowed(fields); }, remove(userId, doc) { // Disable direct client-side user removal for security @@ -579,10 +638,10 @@ Users.allow({ fetch: [], }); -// Non-Admin users can not change to Admin +// Deny any attempts to touch forbidden fields from client updates Users.deny({ - update(userId, board, fieldNames) { - return _.contains(fieldNames, 'isAdmin') && !ReactiveCache.getCurrentUser().isAdmin; + update(userId, doc, fields /*, modifier */) { + return hasForbiddenUserUpdateField(fields); }, fetch: [], }); @@ -774,17 +833,13 @@ Users.helpers({ return ret; }, boards() { - return Boards.userBoards(this._id, null, {}, { sort: { sort: 1 } }); + // Fetch unsorted; sorting is per-user via profile.boardSortIndex + return Boards.userBoards(this._id, null, {}, {}); }, starredBoards() { const { starredBoards = [] } = this.profile || {}; - return Boards.userBoards( - this._id, - false, - { _id: { $in: starredBoards } }, - { sort: { sort: 1 } }, - ); + return Boards.userBoards(this._id, false, { _id: { $in: starredBoards } }, {}); }, hasStarred(boardId) { @@ -799,12 +854,7 @@ Users.helpers({ invitedBoards() { const { invitedBoards = [] } = this.profile || {}; - return Boards.userBoards( - this._id, - false, - { _id: { $in: invitedBoards } }, - { sort: { sort: 1 } }, - ); + return Boards.userBoards(this._id, false, { _id: { $in: invitedBoards } }, {}); }, isInvitedTo(boardId) { @@ -823,6 +873,32 @@ Users.helpers({ } return ret; }, + /** + * Get per-user board sort index for a board, or null when not set + */ + getBoardSortIndex(boardId) { + const mapping = (this.profile && this.profile.boardSortIndex) || {}; + const v = mapping[boardId]; + return typeof v === 'number' ? v : null; + }, + /** + * Sort an array of boards by per-user mapping; fallback to title asc + */ + sortBoardsForUser(boardsArr) { + const mapping = (this.profile && this.profile.boardSortIndex) || {}; + const arr = (boardsArr || []).slice(); + arr.sort((a, b) => { + const ia = typeof mapping[a._id] === 'number' ? mapping[a._id] : Number.POSITIVE_INFINITY; + const ib = typeof mapping[b._id] === 'number' ? mapping[b._id] : Number.POSITIVE_INFINITY; + if (ia !== ib) return ia - ib; + const ta = (a.title || '').toLowerCase(); + const tb = (b.title || '').toLowerCase(); + if (ta < tb) return -1; + if (ta > tb) return 1; + return 0; + }); + return arr; + }, hasSortBy() { // if use doesn't have dragHandle, then we can let user to choose sort list by different order return !this.hasShowDesktopDragHandles(); @@ -875,6 +951,52 @@ Users.helpers({ } }, + getSwimlaneHeightFromStorage(boardId, swimlaneId) { + // For logged-in users, get from profile + if (this._id) { + return this.getSwimlaneHeight(boardId, swimlaneId); + } + + // For non-logged-in users, get from localStorage + try { + const stored = localStorage.getItem('wekan-swimlane-heights'); + if (stored) { + const heights = JSON.parse(stored); + if (heights[boardId] && heights[boardId][swimlaneId]) { + return heights[boardId][swimlaneId]; + } + } + } catch (e) { + console.warn('Error reading swimlane heights from localStorage:', e); + } + + return -1; + }, + + setSwimlaneHeightToStorage(boardId, swimlaneId, height) { + // For logged-in users, save to profile + if (this._id) { + return this.setSwimlaneHeight(boardId, swimlaneId, height); + } + + // For non-logged-in users, save to localStorage + try { + const stored = localStorage.getItem('wekan-swimlane-heights'); + let heights = stored ? JSON.parse(stored) : {}; + + if (!heights[boardId]) { + heights[boardId] = {}; + } + heights[boardId][swimlaneId] = height; + + localStorage.setItem('wekan-swimlane-heights', JSON.stringify(heights)); + return true; + } catch (e) { + console.warn('Error saving swimlane height to localStorage:', e); + return false; + } + }, + /** returns all confirmed move and copy dialog field values *
  • the board, swimlane and list id is stored for each board */ @@ -1003,6 +1125,11 @@ Users.helpers({ return profile.startDayOfWeek; }, + getDateFormat() { + const profile = this.profile || {}; + return profile.dateFormat || 'YYYY-MM-DD'; + }, + getTemplatesBoardId() { return (this.profile || {}).templatesBoardId; }, @@ -1032,6 +1159,144 @@ Users.helpers({ _id: this._id, }); }, + + getListWidthFromStorage(boardId, listId) { + // For logged-in users, get from profile + if (this._id) { + return this.getListWidth(boardId, listId); + } + + // For non-logged-in users, get from localStorage + try { + const stored = localStorage.getItem('wekan-list-widths'); + if (stored) { + const widths = JSON.parse(stored); + if (widths[boardId] && widths[boardId][listId]) { + return widths[boardId][listId]; + } + } + } catch (e) { + console.warn('Error reading list widths from localStorage:', e); + } + + return 270; // Return default width instead of -1 + }, + + setListWidthToStorage(boardId, listId, width) { + // For logged-in users, save to profile + if (this._id) { + return this.setListWidth(boardId, listId, width); + } + + // For non-logged-in users, save to localStorage + try { + const stored = localStorage.getItem('wekan-list-widths'); + let widths = stored ? JSON.parse(stored) : {}; + + if (!widths[boardId]) { + widths[boardId] = {}; + } + widths[boardId][listId] = width; + + localStorage.setItem('wekan-list-widths', JSON.stringify(widths)); + return true; + } catch (e) { + console.warn('Error saving list width to localStorage:', e); + return false; + } + }, + + getListConstraintFromStorage(boardId, listId) { + // For logged-in users, get from profile + if (this._id) { + return this.getListConstraint(boardId, listId); + } + + // For non-logged-in users, get from localStorage + try { + const stored = localStorage.getItem('wekan-list-constraints'); + if (stored) { + const constraints = JSON.parse(stored); + if (constraints[boardId] && constraints[boardId][listId]) { + return constraints[boardId][listId]; + } + } + } catch (e) { + console.warn('Error reading list constraints from localStorage:', e); + } + + return 550; // Return default constraint instead of -1 + }, + + setListConstraintToStorage(boardId, listId, constraint) { + // For logged-in users, save to profile + if (this._id) { + return this.setListConstraint(boardId, listId, constraint); + } + + // For non-logged-in users, save to localStorage + try { + const stored = localStorage.getItem('wekan-list-constraints'); + let constraints = stored ? JSON.parse(stored) : {}; + + if (!constraints[boardId]) { + constraints[boardId] = {}; + } + constraints[boardId][listId] = constraint; + + localStorage.setItem('wekan-list-constraints', JSON.stringify(constraints)); + return true; + } catch (e) { + console.warn('Error saving list constraint to localStorage:', e); + return false; + } + }, + + getSwimlaneHeightFromStorage(boardId, swimlaneId) { + // For logged-in users, get from profile + if (this._id) { + return this.getSwimlaneHeight(boardId, swimlaneId); + } + + // For non-logged-in users, get from localStorage + try { + const stored = localStorage.getItem('wekan-swimlane-heights'); + if (stored) { + const heights = JSON.parse(stored); + if (heights[boardId] && heights[boardId][swimlaneId]) { + return heights[boardId][swimlaneId]; + } + } + } catch (e) { + console.warn('Error reading swimlane heights from localStorage:', e); + } + + return -1; // Return -1 if not found + }, + + setSwimlaneHeightToStorage(boardId, swimlaneId, height) { + // For logged-in users, save to profile + if (this._id) { + return this.setSwimlaneHeight(boardId, swimlaneId, height); + } + + // For non-logged-in users, save to localStorage + try { + const stored = localStorage.getItem('wekan-swimlane-heights'); + let heights = stored ? JSON.parse(stored) : {}; + + if (!heights[boardId]) { + heights[boardId] = {}; + } + heights[boardId][swimlaneId] = height; + + localStorage.setItem('wekan-swimlane-heights', JSON.stringify(heights)); + return true; + } catch (e) { + console.warn('Error saving swimlane height to localStorage:', e); + return false; + } + }, }); Users.mutations({ @@ -1082,6 +1347,19 @@ Users.mutations({ }, }; }, + /** + * Set per-user board sort index for a board + * Stored at profile.boardSortIndex[boardId] = sortIndex (Number) + */ + setBoardSortIndex(boardId, sortIndex) { + const mapping = (this.profile && this.profile.boardSortIndex) || {}; + mapping[boardId] = sortIndex; + return { + $set: { + 'profile.boardSortIndex': mapping, + }, + }; + }, toggleAutoWidth(boardId) { const { autoWidthBoards = {} } = this.profile || {}; autoWidthBoards[boardId] = !autoWidthBoards[boardId]; @@ -1268,6 +1546,14 @@ Users.mutations({ }; }, + setDateFormat(dateFormat) { + return { + $set: { + 'profile.dateFormat': dateFormat, + }, + }; + }, + setBoardView(view) { return { $set: { @@ -1381,10 +1667,98 @@ Meteor.methods({ check(value, String); ReactiveCache.getCurrentUser().setListSortBy(value); }, + toggleBoardStar(boardId) { + check(boardId, String); + if (!this.userId) { + throw new Meteor.Error('not-logged-in', 'User must be logged in'); + } + const user = Users.findOne(this.userId); + if (!user) { + throw new Meteor.Error('user-not-found', 'User not found'); + } + + // Check if board is already starred + const starredBoards = (user.profile && user.profile.starredBoards) || []; + const isStarred = starredBoards.includes(boardId); + + // Build update object + const updateObject = isStarred + ? { $pull: { 'profile.starredBoards': boardId } } + : { $addToSet: { 'profile.starredBoards': boardId } }; + + Users.update(this.userId, updateObject); + }, toggleDesktopDragHandles() { const user = ReactiveCache.getCurrentUser(); user.toggleDesktopHandles(user.hasShowDesktopDragHandles()); }, + // Spaces: create a new space under parentId (or root when null) + createWorkspace({ parentId = null, name }) { + check(name, String); + if (!this.userId) throw new Meteor.Error('not-logged-in'); + const user = Users.findOne(this.userId) || {}; + const tree = (user.profile && user.profile.boardWorkspacesTree) ? EJSON.clone(user.profile.boardWorkspacesTree) : []; + + const newNode = { id: Random.id(), name, children: [] }; + + if (!parentId) { + tree.push(newNode); + } else { + const insertInto = (nodes) => { + for (let n of nodes) { + if (n.id === parentId) { + n.children = n.children || []; + n.children.push(newNode); + return true; + } + if (n.children && n.children.length) { + if (insertInto(n.children)) return true; + } + } + return false; + }; + insertInto(tree); + } + + Users.update(this.userId, { $set: { 'profile.boardWorkspacesTree': tree } }); + return newNode; + }, + // Spaces: set entire tree (used for drag-drop reordering) + setWorkspacesTree(newTree) { + check(newTree, Array); + if (!this.userId) throw new Meteor.Error('not-logged-in'); + Users.update(this.userId, { $set: { 'profile.boardWorkspacesTree': newTree } }); + return true; + }, + // Assign a board to a space + assignBoardToWorkspace(boardId, spaceId) { + check(boardId, String); + check(spaceId, String); + if (!this.userId) throw new Meteor.Error('not-logged-in'); + + const user = Users.findOne(this.userId); + const assignments = user.profile?.boardWorkspaceAssignments || {}; + assignments[boardId] = spaceId; + + Users.update(this.userId, { + $set: { 'profile.boardWorkspaceAssignments': assignments } + }); + return true; + }, + // Remove a board assignment (moves it back to Remaining) + unassignBoardFromWorkspace(boardId) { + check(boardId, String); + if (!this.userId) throw new Meteor.Error('not-logged-in'); + + const user = Users.findOne(this.userId); + const assignments = user.profile?.boardWorkspaceAssignments || {}; + delete assignments[boardId]; + + Users.update(this.userId, { + $set: { 'profile.boardWorkspaceAssignments': assignments } + }); + return true; + }, toggleHideCheckedItems() { const user = ReactiveCache.getCurrentUser(); user.toggleHideCheckedItems(); @@ -1413,6 +1787,10 @@ Meteor.methods({ check(startDay, Number); ReactiveCache.getCurrentUser().setStartDayOfWeek(startDay); }, + changeDateFormat(dateFormat) { + check(dateFormat, String); + ReactiveCache.getCurrentUser().setDateFormat(dateFormat); + }, applyListWidth(boardId, listId, width, constraint) { check(boardId, String); check(listId, String); @@ -1429,6 +1807,30 @@ Meteor.methods({ const user = ReactiveCache.getCurrentUser(); user.setSwimlaneHeight(boardId, swimlaneId, height); }, + + applySwimlaneHeightToStorage(boardId, swimlaneId, height) { + check(boardId, String); + check(swimlaneId, String); + check(height, Number); + const user = ReactiveCache.getCurrentUser(); + if (user) { + user.setSwimlaneHeightToStorage(boardId, swimlaneId, height); + } + // For non-logged-in users, the client-side code will handle localStorage + }, + + applyListWidthToStorage(boardId, listId, width, constraint) { + check(boardId, String); + check(listId, String); + check(width, Number); + check(constraint, Number); + const user = ReactiveCache.getCurrentUser(); + if (user) { + user.setListWidthToStorage(boardId, listId, width); + user.setListConstraintToStorage(boardId, listId, constraint); + } + // For non-logged-in users, the client-side code will handle localStorage + }, setZoomLevel(level) { check(level, Number); const user = ReactiveCache.getCurrentUser(); @@ -1439,6 +1841,14 @@ Meteor.methods({ const user = ReactiveCache.getCurrentUser(); user.setMobileMode(enabled); }, + setBoardView(view) { + check(view, String); + const user = ReactiveCache.getCurrentUser(); + if (!user) { + throw new Meteor.Error('not-authorized', 'Must be logged in'); + } + user.setBoardView(view); + }, }); if (Meteor.isServer) { @@ -1850,7 +2260,7 @@ if (Meteor.isServer) { }, }); Accounts.onCreateUser((options, user) => { - const userCount = ReactiveCache.getUsers({}, {}, true).countDocuments(); + const userCount = ReactiveCache.getUsers({}, {}, true).count(); user.isAdmin = userCount === 0; if (user.services.oidc) { @@ -2138,7 +2548,7 @@ if (Meteor.isServer) { const future3 = new Future(); Boards.insert( { - title: TAPi18n.__('templates'), + title: TAPi18n && TAPi18n.i18n ? TAPi18n.__('templates') : 'Templates', permission: 'private', type: 'template-container', }, @@ -2154,7 +2564,7 @@ if (Meteor.isServer) { // Insert the card templates swimlane Swimlanes.insert( { - title: TAPi18n.__('card-templates-swimlane'), + title: TAPi18n && TAPi18n.i18n ? TAPi18n.__('card-templates-swimlane') : 'Card Templates', boardId, sort: 1, type: 'template-container', @@ -2174,7 +2584,7 @@ if (Meteor.isServer) { // Insert the list templates swimlane Swimlanes.insert( { - title: TAPi18n.__('list-templates-swimlane'), + title: TAPi18n && TAPi18n.i18n ? TAPi18n.__('list-templates-swimlane') : 'List Templates', boardId, sort: 2, type: 'template-container', @@ -2194,7 +2604,7 @@ if (Meteor.isServer) { // Insert the board templates swimlane Swimlanes.insert( { - title: TAPi18n.__('board-templates-swimlane'), + title: TAPi18n && TAPi18n.i18n ? TAPi18n.__('board-templates-swimlane') : 'Board Templates', boardId, sort: 3, type: 'template-container', diff --git a/models/wekanCreator.js b/models/wekanCreator.js index b429a9427..4d7f4425d 100644 --- a/models/wekanCreator.js +++ b/models/wekanCreator.js @@ -1,9 +1,28 @@ import { ReactiveCache } from '/imports/reactiveCache'; -import moment from 'moment/min/moment-with-locales'; +import { + formatDateTime, + formatDate, + formatTime, + getISOWeek, + isValidDate, + isBefore, + isAfter, + isSame, + add, + subtract, + startOf, + endOf, + format, + parseDate, + now, + createDate, + fromNow, + calendar +} from '/imports/lib/dateUtils'; const DateString = Match.Where(function(dateAsString) { check(dateAsString, String); - return moment(dateAsString, moment.ISO_8601).isValid(); + return isValidDate(new Date(dateAsString)); }); export class WekanCreator { diff --git a/package-lock.json b/package-lock.json index 646dec774..c22f9d0de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,13 @@ { "name": "wekan", - "version": "v8.01.0", + "version": "v8.17.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/runtime": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", - "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", - "requires": { - "regenerator-runtime": "^0.14.0" - } + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==" }, "@fast-csv/format": { "version": "4.3.5", @@ -60,6 +57,17 @@ "tar": "^6.1.11" } }, + "@meteorjs/reify": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@meteorjs/reify/-/reify-0.25.4.tgz", + "integrity": "sha512-/HwynJK85QtS2Rm26M9TS8aEMnqVJ2TIzJNJTGAQz+G6cTYmJGWaU4nFH96oxiDIBbnT6Y3TfX92HDuS9TtNRg==", + "requires": { + "acorn": "^8.8.1", + "magic-string": "^0.25.3", + "periscopic": "^2.0.3", + "semver": "^7.5.4" + } + }, "@rwap/jquery-ui-touch-punch": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@rwap/jquery-ui-touch-punch/-/jquery-ui-touch-punch-1.0.11.tgz", @@ -108,6 +116,11 @@ "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, + "@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" + }, "@types/node": { "version": "14.18.63", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", @@ -159,22 +172,29 @@ "@wekanteam/meteor-globals": "^1.1.4" } }, - "@zxing/text-encoding": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", - "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", - "optional": true - }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, "abstract-logging": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==" }, + "acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==" + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -297,14 +317,9 @@ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" }, "async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" }, "backoff": { "version": "2.5.0", @@ -353,14 +368,6 @@ "readable-stream": "^3.4.0" } }, - "block-stream2": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-2.1.0.tgz", - "integrity": "sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==", - "requires": { - "readable-stream": "^3.4.0" - } - }, "bluebird": { "version": "3.4.7", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", @@ -380,11 +387,6 @@ "concat-map": "0.0.1" } }, - "browser-or-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz", - "integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==" - }, "bson": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/bson/-/bson-4.7.2.tgz", @@ -422,16 +424,6 @@ "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==" }, - "call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "requires": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - } - }, "call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -612,9 +604,9 @@ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" }, "dayjs": { - "version": "1.11.13", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", - "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" + "version": "1.11.18", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", + "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==" }, "debug": { "version": "4.3.4", @@ -624,21 +616,6 @@ "ms": "2.1.2" } }, - "decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" - }, - "define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "requires": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - } - }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -679,9 +656,9 @@ } }, "dompurify": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz", - "integrity": "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", "requires": { "@types/trusted-types": "^2.0.7" } @@ -756,9 +733,9 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "requires": { "once": "^1.4.0" } @@ -823,6 +800,21 @@ "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==" }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, "extsprintf": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", @@ -847,14 +839,6 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, - "fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", - "requires": { - "strnum": "^1.0.5" - } - }, "fibers": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/fibers/-/fibers-5.0.3.tgz", @@ -885,25 +869,12 @@ "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==" }, - "filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==" - }, "flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -1034,14 +1005,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "requires": { - "get-intrinsic": "^1.2.2" - } - }, "has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", @@ -1052,14 +1015,6 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -1130,20 +1085,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==" - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -1154,20 +1095,12 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "requires": { - "which-typed-array": "^1.1.11" + "@types/estree": "*" } }, "isarray": { @@ -1193,11 +1126,6 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, - "json-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-stream/-/json-stream-1.0.0.tgz", - "integrity": "sha512-H/ZGY0nIAg3QcOwE1QN/rK/Fa7gJn7Ii5obwp6zyPO4xiPNwpIMjqy2gwjBEGqzkF/vSWEIBQCBuN19hYiL6Qg==" - }, "jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -1337,11 +1265,6 @@ "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==" }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -1421,6 +1344,14 @@ "yallist": "^4.0.0" } }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -1526,7 +1457,8 @@ "dependencies": { "@meteorjs/browserify-sign": { "version": "4.2.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/@meteorjs/browserify-sign/-/browserify-sign-4.2.6.tgz", + "integrity": "sha512-xnQRbIrjHxaVbOEbzbcdav4QDRTnfRAVHi21SPosnGNiIHTdTeGQGmTF/f7GwntxqynabSifdBHeGA7W8lIKSQ==", "requires": { "bn.js": "^5.2.1", "brorand": "^1.1.0", @@ -1546,11 +1478,13 @@ "dependencies": { "isarray": { "version": "1.0.0", - "bundled": true + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "readable-stream": { "version": "2.3.8", - "bundled": true, + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1563,20 +1497,23 @@ "dependencies": { "safe-buffer": { "version": "5.1.2", - "bundled": true + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, "string_decoder": { "version": "1.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" }, "dependencies": { "safe-buffer": { "version": "5.1.2", - "bundled": true + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } } @@ -1584,7 +1521,8 @@ }, "@meteorjs/create-ecdh": { "version": "4.0.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/@meteorjs/create-ecdh/-/create-ecdh-4.0.5.tgz", + "integrity": "sha512-dhn3AICsDlIZ5qY/Qu+QOL+ZGKaHcGss4PQ3CfmAF3f+o5fPJ2aDJcxd5f2au2k6sxyNqvCsLAFYFHXxHoH9yQ==", "requires": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -1597,13 +1535,15 @@ "dependencies": { "bn.js": { "version": "4.12.2", - "bundled": true + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==" } } }, "@meteorjs/crypto-browserify": { "version": "3.12.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/@meteorjs/crypto-browserify/-/crypto-browserify-3.12.4.tgz", + "integrity": "sha512-K5Sgvxef93Zrw5T9cJxKuNVgpl1C2W8cfcicN6HKy98G6RoIrx6hikwWnq8FlagvOzdIQEC2s+SMn7UFNSK0eA==", "requires": { "@meteorjs/browserify-sign": "^4.2.3", "@meteorjs/create-ecdh": "^4.0.4", @@ -1621,7 +1561,8 @@ }, "asn1.js": { "version": "4.10.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", @@ -1630,13 +1571,15 @@ "dependencies": { "bn.js": { "version": "4.12.2", - "bundled": true + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==" } } }, "assert": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", "requires": { "call-bind": "^1.0.2", "is-nan": "^1.3.2", @@ -1647,26 +1590,31 @@ }, "available-typed-arrays": { "version": "1.0.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "requires": { "possible-typed-array-names": "^1.0.0" } }, "base64-js": { "version": "1.5.1", - "bundled": true + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "bn.js": { "version": "5.2.2", - "bundled": true + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==" }, "brorand": { "version": "1.1.0", - "bundled": true + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, "browserify-aes": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "requires": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -1678,7 +1626,8 @@ }, "browserify-cipher": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "requires": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", @@ -1687,7 +1636,8 @@ }, "browserify-des": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "requires": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", @@ -1697,7 +1647,8 @@ }, "browserify-rsa": { "version": "4.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", + "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", "requires": { "bn.js": "^5.2.1", "randombytes": "^2.1.0", @@ -1706,14 +1657,16 @@ }, "browserify-zlib": { "version": "0.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "requires": { "pako": "~1.0.5" } }, "buffer": { "version": "5.7.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -1721,15 +1674,18 @@ }, "buffer-xor": { "version": "1.0.3", - "bundled": true + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" }, "builtin-status-codes": { "version": "3.0.0", - "bundled": true + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" }, "call-bind": { "version": "1.0.8", - "bundled": true, + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "requires": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", @@ -1739,7 +1695,8 @@ }, "call-bind-apply-helpers": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "requires": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -1747,7 +1704,8 @@ }, "call-bound": { "version": "1.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "requires": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" @@ -1755,7 +1713,8 @@ }, "cipher-base": { "version": "1.0.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", + "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", "requires": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1" @@ -1763,19 +1722,23 @@ }, "console-browserify": { "version": "1.2.0", - "bundled": true + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" }, "constants-browserify": { "version": "1.0.0", - "bundled": true + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==" }, "core-util-is": { "version": "1.0.3", - "bundled": true + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "create-hash": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -1786,7 +1749,8 @@ }, "create-hmac": { "version": "1.1.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "requires": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -1798,7 +1762,8 @@ }, "define-data-property": { "version": "1.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "requires": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -1807,7 +1772,8 @@ }, "define-properties": { "version": "1.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "requires": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -1816,7 +1782,8 @@ }, "des.js": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", "requires": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" @@ -1824,7 +1791,8 @@ }, "diffie-hellman": { "version": "5.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "requires": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", @@ -1833,17 +1801,20 @@ "dependencies": { "bn.js": { "version": "4.12.2", - "bundled": true + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==" } } }, "domain-browser": { "version": "4.23.0", - "bundled": true + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", + "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==" }, "dunder-proto": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "requires": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -1852,26 +1823,31 @@ }, "es-define-property": { "version": "1.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" }, "es-errors": { "version": "1.3.0", - "bundled": true + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" }, "es-object-atoms": { "version": "1.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "requires": { "es-errors": "^1.3.0" } }, "events": { "version": "3.3.0", - "bundled": true + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" }, "evp_bytestokey": { "version": "1.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "requires": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -1879,18 +1855,21 @@ }, "for-each": { "version": "0.3.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "requires": { "is-callable": "^1.2.7" } }, "function-bind": { "version": "1.1.2", - "bundled": true + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "get-intrinsic": { "version": "1.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "requires": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -1906,7 +1885,8 @@ }, "get-proto": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "requires": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -1914,29 +1894,34 @@ }, "gopd": { "version": "1.2.0", - "bundled": true + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" }, "has-property-descriptors": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "requires": { "es-define-property": "^1.0.0" } }, "has-symbols": { "version": "1.1.0", - "bundled": true + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" }, "has-tostringtag": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "requires": { "has-symbols": "^1.0.3" } }, "hash-base": { "version": "3.0.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz", + "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==", "requires": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1" @@ -1944,7 +1929,8 @@ }, "hash.js": { "version": "1.1.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -1952,14 +1938,16 @@ }, "hasown": { "version": "2.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "requires": { "function-bind": "^1.1.2" } }, "hmac-drbg": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "requires": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -1968,19 +1956,23 @@ }, "https-browserify": { "version": "1.0.0", - "bundled": true + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" }, "ieee754": { "version": "1.2.1", - "bundled": true + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "inherits": { "version": "2.0.4", - "bundled": true + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "is-arguments": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", "requires": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" @@ -1988,11 +1980,13 @@ }, "is-callable": { "version": "1.2.7", - "bundled": true + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" }, "is-generator-function": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "requires": { "call-bound": "^1.0.3", "get-proto": "^1.0.0", @@ -2002,7 +1996,8 @@ }, "is-nan": { "version": "1.3.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" @@ -2010,7 +2005,8 @@ }, "is-regex": { "version": "1.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "requires": { "call-bound": "^1.0.2", "gopd": "^1.2.0", @@ -2020,22 +2016,26 @@ }, "is-typed-array": { "version": "1.1.15", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "requires": { "which-typed-array": "^1.1.16" } }, "isarray": { "version": "2.0.5", - "bundled": true + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "math-intrinsics": { "version": "1.1.0", - "bundled": true + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" }, "md5.js": { "version": "1.3.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -2044,7 +2044,8 @@ }, "miller-rabin": { "version": "4.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" @@ -2052,25 +2053,30 @@ "dependencies": { "bn.js": { "version": "4.12.2", - "bundled": true + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==" } } }, "minimalistic-assert": { "version": "1.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" }, "object-inspect": { "version": "1.13.4", - "bundled": true + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" }, "object-is": { "version": "1.1.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", "requires": { "call-bind": "^1.0.7", "define-properties": "^1.2.1" @@ -2078,11 +2084,13 @@ }, "object-keys": { "version": "1.1.1", - "bundled": true + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object.assign": { "version": "4.1.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "requires": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", @@ -2094,15 +2102,18 @@ }, "os-browserify": { "version": "0.3.0", - "bundled": true + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" }, "pako": { "version": "1.0.11", - "bundled": true + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, "parse-asn1": { "version": "5.1.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "requires": { "asn1.js": "^4.10.1", "browserify-aes": "^1.2.0", @@ -2114,11 +2125,13 @@ }, "path-browserify": { "version": "1.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" }, "pbkdf2": { "version": "3.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz", + "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", "requires": { "create-hash": "~1.1.3", "create-hmac": "^1.1.7", @@ -2130,7 +2143,8 @@ "dependencies": { "create-hash": { "version": "1.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", + "integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==", "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -2140,14 +2154,16 @@ }, "hash-base": { "version": "2.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", + "integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==", "requires": { "inherits": "^2.0.1" } }, "ripemd160": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", + "integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==", "requires": { "hash-base": "^2.0.0", "inherits": "^2.0.1" @@ -2157,19 +2173,23 @@ }, "possible-typed-array-names": { "version": "1.1.0", - "bundled": true + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==" }, "process": { "version": "0.11.10", - "bundled": true + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" }, "process-nextick-args": { "version": "2.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "public-encrypt": { "version": "4.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "requires": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", @@ -2181,35 +2201,41 @@ "dependencies": { "bn.js": { "version": "4.12.2", - "bundled": true + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==" } } }, "punycode": { "version": "1.4.1", - "bundled": true + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" }, "qs": { "version": "6.14.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "requires": { "side-channel": "^1.1.0" } }, "querystring-es3": { "version": "0.2.1", - "bundled": true + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==" }, "randombytes": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "requires": { "safe-buffer": "^5.1.0" } }, "randomfill": { "version": "1.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "requires": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" @@ -2217,7 +2243,8 @@ }, "readable-stream": { "version": "3.6.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2226,7 +2253,8 @@ }, "ripemd160": { "version": "2.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -2234,11 +2262,13 @@ }, "safe-buffer": { "version": "5.2.1", - "bundled": true + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safe-regex-test": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "requires": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -2247,7 +2277,8 @@ }, "set-function-length": { "version": "1.2.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "requires": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -2259,11 +2290,13 @@ }, "setimmediate": { "version": "1.0.5", - "bundled": true + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "sha.js": { "version": "2.4.12", - "bundled": true, + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", "requires": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", @@ -2272,7 +2305,8 @@ }, "side-channel": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "requires": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", @@ -2283,7 +2317,8 @@ }, "side-channel-list": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "requires": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" @@ -2291,7 +2326,8 @@ }, "side-channel-map": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "requires": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -2301,7 +2337,8 @@ }, "side-channel-weakmap": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "requires": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -2312,7 +2349,8 @@ }, "stream-browserify": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", "requires": { "inherits": "~2.0.4", "readable-stream": "^3.5.0" @@ -2320,7 +2358,8 @@ }, "stream-http": { "version": "3.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", "requires": { "builtin-status-codes": "^3.0.0", "inherits": "^2.0.4", @@ -2330,21 +2369,24 @@ }, "string_decoder": { "version": "1.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "requires": { "safe-buffer": "~5.2.0" } }, "timers-browserify": { "version": "2.0.12", - "bundled": true, + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", "requires": { "setimmediate": "^1.0.4" } }, "to-buffer": { "version": "1.2.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz", + "integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==", "requires": { "isarray": "^2.0.5", "safe-buffer": "^5.2.1", @@ -2353,11 +2395,13 @@ }, "tty-browserify": { "version": "0.0.1", - "bundled": true + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==" }, "typed-array-buffer": { "version": "1.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "requires": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", @@ -2366,7 +2410,8 @@ }, "url": { "version": "0.11.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", "requires": { "punycode": "^1.4.1", "qs": "^6.12.3" @@ -2374,7 +2419,8 @@ }, "util": { "version": "0.12.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "requires": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -2385,15 +2431,18 @@ }, "util-deprecate": { "version": "1.0.2", - "bundled": true + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "vm-browserify": { "version": "1.1.2", - "bundled": true + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" }, "which-typed-array": { "version": "1.1.19", - "bundled": true, + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "requires": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", @@ -2406,7 +2455,8 @@ }, "xtend": { "version": "4.0.2", - "bundled": true + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" } } }, @@ -2420,19 +2470,6 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2446,27 +2483,6 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, - "minio": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minio/-/minio-7.1.3.tgz", - "integrity": "sha512-xPrLjWkTT5E7H7VnzOjF//xBp9I40jYB4aWhb2xTFopXXfw+Wo82DDWngdUju7Doy3Wk7R8C4LAgwhLHHnf0wA==", - "requires": { - "async": "^3.2.4", - "block-stream2": "^2.1.0", - "browser-or-node": "^2.1.1", - "buffer-crc32": "^0.2.13", - "fast-xml-parser": "^4.2.2", - "ipaddr.js": "^2.0.1", - "json-stream": "^1.0.0", - "lodash": "^4.17.21", - "mime-types": "^2.1.35", - "query-string": "^7.1.3", - "through2": "^4.0.2", - "web-encoding": "^1.1.5", - "xml": "^1.0.1", - "xml2js": "^0.5.0" - } - }, "minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -2501,11 +2517,6 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, - "moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==" - }, "mongo-object": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mongo-object/-/mongo-object-3.0.1.tgz", @@ -2644,9 +2655,9 @@ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, "papaparse": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", - "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw==" + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.3.tgz", + "integrity": "sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==" }, "parse-ms": { "version": "2.1.0", @@ -2676,6 +2687,15 @@ "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==" }, + "periscopic": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-2.0.3.tgz", + "integrity": "sha512-FuCZe61mWxQOJAQFEfmt9FjzebRlcpFz8sFPbyaCKtdusPkMEbA9ey0eARnRav5zAhmXznhaQkKGFAPn7X9NUw==", + "requires": { + "estree-walker": "^2.0.2", + "is-reference": "^1.1.4" + } + }, "possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -2694,6 +2714,11 @@ "parse-ms": "^2.1.0" } }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -2712,17 +2737,6 @@ "side-channel": "^1.0.6" } }, - "query-string": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", - "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", - "requires": { - "decode-uri-component": "^0.2.2", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - } - }, "readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -2734,11 +2748,34 @@ } }, "readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", + "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", "requires": { - "readable-stream": "^3.6.0" + "readable-stream": "^4.7.0" + }, + "dependencies": { + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "requires": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + } + } } }, "readdir-glob": { @@ -2767,11 +2804,6 @@ } } }, - "regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2790,11 +2822,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" - }, "saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", @@ -2816,17 +2843,6 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, - "set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "requires": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - } - }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -2947,6 +2963,11 @@ "source-map": "^0.6.0" } }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, "speech-rule-engine": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz", @@ -2964,16 +2985,6 @@ } } }, - "split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" - }, - "strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==" - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -3000,11 +3011,6 @@ "ansi-regex": "^5.0.1" } }, - "strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" - }, "strtok3": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", @@ -3048,14 +3054,6 @@ "readable-stream": "^3.1.1" } }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "requires": { - "readable-stream": "3" - } - }, "tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", @@ -3309,18 +3307,6 @@ "punycode": "^2.1.0" } }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -3378,15 +3364,6 @@ } } }, - "web-encoding": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/web-encoding/-/web-encoding-1.1.5.tgz", - "integrity": "sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==", - "requires": { - "@zxing/text-encoding": "0.9.0", - "util": "^0.12.3" - } - }, "web-resource-inliner": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-6.0.1.tgz", @@ -3435,18 +3412,6 @@ "webidl-conversions": "^3.0.0" } }, - "which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, "wicked-good-xpath": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz", @@ -3465,25 +3430,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" - }, - "xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" - }, "xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", diff --git a/package.json b/package.json index 6d7a1dcf1..0b2a6fb67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wekan", - "version": "v8.01.0", + "version": "v8.17.0", "description": "Open-Source kanban", "private": true, "repository": { @@ -17,25 +17,26 @@ "sinon": "^13.0.2" }, "dependencies": { - "@babel/runtime": "^7.26.10", + "@babel/runtime": "^7.28.4", "@mapbox/node-pre-gyp": "^1.0.10", + "@meteorjs/reify": "^0.25.4", "@rwap/jquery-ui-touch-punch": "^1.0.11", "@wekanteam/dragscroll": "https://github.com/wekan/dragscroll.git", - "@wekanteam/exceljs": "https://github.com/wekan/exceljs.git", + "@wekanteam/exceljs": "git+https://github.com/wekan/exceljs.git", "@wekanteam/html-to-markdown": "^1.0.2", "@wekanteam/meteor-globals": "^1.1.4", "@wekanteam/meteor-reactive-cache": "^1.0.6", "ajv": "^6.12.6", "bcryptjs": "^2.4.3", - "bson": "^4.5.2", + "bson": "^4.7.2", "chart.js": "^4.5.0", - "dompurify": "^3.2.4", + "dompurify": "^3.2.7", "es6-promise": "^4.2.4", "escape-string-regexp": "^5.0.0", "fibers": "^5.0.3", "file-type": "^16.5.4", "filesize": "^8.0.7", - "i18next": "^21.6.16", + "i18next": "^21.10.0", "i18next-sprintf-postprocessor": "^0.2.2", "jquery": "^3.7.1", "jquery-ui": "^1.13.3", @@ -46,16 +47,8 @@ "markdown-it-mathjax3": "^4.3.2", "meteor-accounts-t9n": "^2.6.0", "meteor-node-stubs": "^1.2.24", - "minio": "^7.1.3", - "moment": "^2.29.4", - "mongodb3legacy": "npm:mongodb@3.7.4", - "mongodb4legacy": "npm:mongodb@4.17.2", - "mongodb5legacy": "npm:mongodb@5.9.2", - "mongodb6legacy": "npm:mongodb@6.3.0", - "mongodb7legacy": "npm:mongodb@7.0.1", - "mongodb8legacy": "npm:mongodb@6.9.0", "os": "^0.1.2", - "papaparse": "^5.3.1", + "papaparse": "^5.5.3", "pretty-ms": "^7.0.1", "qs": "^6.13.0", "simpl-schema": "^3.4.6", diff --git a/packages/markdown/src/secureDOMPurify.js b/packages/markdown/src/secureDOMPurify.js index 4deee4d23..898687dad 100644 --- a/packages/markdown/src/secureDOMPurify.js +++ b/packages/markdown/src/secureDOMPurify.js @@ -3,43 +3,25 @@ import DOMPurify from 'dompurify'; // Centralized secure DOMPurify configuration to prevent XSS and CSS injection attacks export function getSecureDOMPurifyConfig() { return { - // Block dangerous elements that can cause XSS and CSS injection - FORBID_TAGS: [ - 'svg', 'defs', 'use', 'g', 'symbol', 'marker', 'pattern', 'mask', 'clipPath', - 'linearGradient', 'radialGradient', 'stop', 'animate', 'animateTransform', - 'animateMotion', 'set', 'switch', 'foreignObject', 'script', 'style', 'link', - 'meta', 'iframe', 'object', 'embed', 'applet', 'form', 'input', 'textarea', - 'select', 'option', 'button', 'label', 'fieldset', 'legend', 'frameset', - 'frame', 'noframes', 'base', 'basefont', 'isindex', 'dir', 'menu', 'menuitem' - ], - // Block dangerous attributes that can cause XSS and CSS injection - FORBID_ATTR: [ - 'xlink:href', 'href', 'onload', 'onerror', 'onclick', 'onmouseover', - 'onfocus', 'onblur', 'onchange', 'onsubmit', 'onreset', 'onselect', - 'onunload', 'onresize', 'onscroll', 'onkeydown', 'onkeyup', 'onkeypress', - 'onmousedown', 'onmouseup', 'onmouseover', 'onmouseout', 'onmousemove', - 'ondblclick', 'oncontextmenu', 'onwheel', 'ontouchstart', 'ontouchend', - 'ontouchmove', 'ontouchcancel', 'onabort', 'oncanplay', 'oncanplaythrough', - 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onloadeddata', - 'onloadedmetadata', 'onloadstart', 'onpause', 'onplay', 'onplaying', - 'onprogress', 'onratechange', 'onseeked', 'onseeking', 'onstalled', - 'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting', 'onbeforeunload', - 'onhashchange', 'onpagehide', 'onpageshow', 'onpopstate', 'onstorage', - 'onunload', 'style', 'class', 'id', 'data-*', 'aria-*' - ], - // Allow only safe image formats and protocols + // Allow common markdown elements including anchor tags + ALLOWED_TAGS: ['a', 'p', 'br', 'strong', 'em', 'u', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'img', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'hr', 'div', 'span'], + // Allow safe attributes including href for anchor tags + ALLOWED_ATTR: ['href', 'title', 'alt', 'src', 'width', 'height', 'target', 'rel'], + // Allow safe protocols for links ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i, - // Remove dangerous protocols + // Allow unknown protocols but be cautious ALLOW_UNKNOWN_PROTOCOLS: false, - // Sanitize URLs to prevent malicious content loading + // Sanitize DOM for security SANITIZE_DOM: true, - // Remove dangerous elements completely - KEEP_CONTENT: false, - // Additional security measures - ADD_ATTR: [], + // Keep content but sanitize it + KEEP_CONTENT: true, + // Block dangerous elements that can cause XSS + FORBID_TAGS: ['script', 'style', 'iframe', 'object', 'embed', 'applet', 'svg', 'defs', 'use', 'g', 'symbol', 'marker', 'pattern', 'mask', 'clipPath', 'linearGradient', 'radialGradient', 'stop', 'animate', 'animateTransform', 'animateMotion', 'set', 'switch', 'foreignObject', 'link', 'meta', 'form', 'input', 'textarea', 'select', 'option', 'button', 'label', 'fieldset', 'legend', 'frameset', 'frame', 'noframes', 'base', 'basefont', 'isindex', 'dir', 'menu', 'menuitem'], + // Block dangerous attributes but allow safe href + FORBID_ATTR: ['xlink:href', 'onload', 'onerror', 'onclick', 'onmouseover', 'onfocus', 'onblur', 'onchange', 'onsubmit', 'onreset', 'onselect', 'onunload', 'onresize', 'onscroll', 'onkeydown', 'onkeyup', 'onkeypress', 'onmousedown', 'onmouseup', 'onmouseover', 'onmouseout', 'onmousemove', 'ondblclick', 'oncontextmenu', 'onwheel', 'ontouchstart', 'ontouchend', 'ontouchmove', 'ontouchcancel', 'onabort', 'oncanplay', 'oncanplaythrough', 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onpause', 'onplay', 'onplaying', 'onprogress', 'onratechange', 'onseeked', 'onseeking', 'onstalled', 'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting', 'onbeforeunload', 'onhashchange', 'onpagehide', 'onpageshow', 'onpopstate', 'onstorage', 'onunload', 'style', 'class', 'id', 'data-*', 'aria-*'], // Block data URIs that could contain malicious content ALLOW_DATA_ATTR: false, - // Custom hook to further sanitize content + // Custom hooks for additional security HOOKS: { uponSanitizeElement: function(node, data) { // Block any remaining dangerous elements @@ -123,6 +105,19 @@ export function getSecureDOMPurifyConfig() { return false; } + // Allow href attribute for anchor tags only + if (data.attrName === 'href') { + // Only allow href on anchor tags + if (node.tagName && node.tagName.toLowerCase() === 'a') { + return true; + } else { + if (process.env.DEBUG === 'true') { + console.warn('Blocked href attribute on non-anchor element:', node.tagName); + } + return false; + } + } + return true; } } diff --git a/packages/markdown/src/template-integration.js b/packages/markdown/src/template-integration.js index d1b7523fa..e845416c9 100644 --- a/packages/markdown/src/template-integration.js +++ b/packages/markdown/src/template-integration.js @@ -36,11 +36,21 @@ for(var i=0; i