Compare commits
24 Commits
fix/kan-41
...
security/a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
641237de83 | ||
|
|
a6780e3e28 | ||
|
|
2c5195a2b8 | ||
|
|
793fa30162 | ||
|
|
af63719de5 | ||
|
|
52fd624b81 | ||
|
|
b4d4810f45 | ||
|
|
239d152340 | ||
|
|
f294760747 | ||
|
|
280d8f66dd | ||
|
|
eeae23a24c | ||
|
|
d81950b8bd | ||
|
|
e530f39360 | ||
|
|
bd25fb33f7 | ||
|
|
93f2816b37 | ||
|
|
2292b972c4 | ||
|
|
af36fb133a | ||
|
|
9cb1fb5218 | ||
|
|
5f190b92de | ||
|
|
48a1f39588 | ||
|
|
c7fce10fa7 | ||
|
|
094e1d139d | ||
|
|
fae169c691 | ||
|
|
91bc319cf1 |
43
.github/workflows/docker-publish.yml
vendored
43
.github/workflows/docker-publish.yml
vendored
@@ -6,8 +6,6 @@ name: Docker
|
||||
# documentation.
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "21 21 * * *"
|
||||
push:
|
||||
# Only trigger on tags (releases), not main branch pushes
|
||||
# Main branch builds are handled by workflow_run after Translate completes
|
||||
@@ -26,6 +24,7 @@ env:
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
MIGRATE_IMAGE_NAME: ${{ github.repository }}-migrate
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -83,7 +82,22 @@ jobs:
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
type=raw,value=latest,enable=${{ github.ref_type == 'tag' }}
|
||||
type=raw,value=edge,enable={{is_default_branch}}
|
||||
|
||||
- name: Extract Docker metadata (migrate)
|
||||
id: meta-migrate
|
||||
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.MIGRATE_IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=raw,value=latest,enable=${{ github.ref_type == 'tag' }}
|
||||
type=raw,value=edge,enable={{is_default_branch}}
|
||||
|
||||
# Extract version from git tag or ref
|
||||
# Uses git describe to get latest tag + commit hash in SemVer format: 1.2.3+abc1234
|
||||
@@ -138,6 +152,22 @@ jobs:
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Build and push migrate Docker image
|
||||
id: build-and-push-migrate
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
|
||||
with:
|
||||
context: .
|
||||
file: apps/web/Dockerfile
|
||||
target: migrate
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.meta-migrate.outputs.tags }}
|
||||
labels: ${{ steps.meta-migrate.outputs.labels }}
|
||||
build-args: |
|
||||
APP_VERSION=${{ steps.version.outputs.version }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
# Sign the resulting Docker image digest except on PRs.
|
||||
# This will only write to the public Rekor transparency log when the Docker
|
||||
# repository is public to avoid leaking data. If you would like to publish
|
||||
@@ -152,3 +182,10 @@ jobs:
|
||||
# This step uses the identity token to provision an ephemeral certificate
|
||||
# against the sigstore community Fulcio instance.
|
||||
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
|
||||
|
||||
- name: Sign the published migrate Docker image
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
env:
|
||||
TAGS: ${{ steps.meta-migrate.outputs.tags }}
|
||||
DIGEST: ${{ steps.build-and-push-migrate.outputs.digest }}
|
||||
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
|
||||
|
||||
23
.github/workflows/translate.yml
vendored
23
.github/workflows/translate.yml
vendored
@@ -14,16 +14,24 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v2
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --filter @kan/web...
|
||||
|
||||
- name: Extract translations
|
||||
working-directory: apps/web
|
||||
run: npx --yes @lingui/cli extract
|
||||
|
||||
run: pnpm lingui:extract
|
||||
|
||||
- name: Lingo.dev
|
||||
uses: lingodotdev/lingo.dev@main
|
||||
with:
|
||||
@@ -33,11 +41,11 @@ jobs:
|
||||
commit-author-name: "${{ github.actor }}"
|
||||
commit-author-email: "${{ github.actor }}@users.noreply.github.com"
|
||||
parallel: true
|
||||
|
||||
|
||||
- name: Compile translations
|
||||
working-directory: apps/web
|
||||
run: npx --yes @lingui/cli compile --typescript
|
||||
|
||||
run: pnpm lingui:compile
|
||||
|
||||
- name: Commit compiled translations
|
||||
run: |
|
||||
git config --local user.email "${{ github.actor }}@users.noreply.github.com"
|
||||
@@ -46,4 +54,3 @@ jobs:
|
||||
git add apps/web/src/locales/*/messages.ts
|
||||
git diff --staged --quiet || (git commit -m "chore: compile translations" && git push)
|
||||
fi
|
||||
|
||||
|
||||
56
README.md
56
README.md
@@ -57,39 +57,61 @@ The easiest way to deploy Kan is through Railway. We've partnered with Railway t
|
||||
|
||||
### Docker Compose
|
||||
|
||||
Alternatively, you can self-host Kan with Docker Compose. This will set up everything for you including your postgres database.
|
||||
Alternatively, you can self-host Kan with Docker Compose. This will set up everything for you including your postgres database and automatically run migrations.
|
||||
|
||||
1. Create a new file called `docker-compose.yml` and paste the following configuration:
|
||||
1. Create a `.env` file with your environment variables (see [Environment Variables](#environment-variables-) section below)
|
||||
|
||||
2. Use the provided `docker-compose.yml` file or create your own with the following configuration:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
migrate:
|
||||
image: ghcr.io/kanbn/kan-migrate:latest
|
||||
container_name: kan-migrate
|
||||
networks:
|
||||
- kan-network
|
||||
environment:
|
||||
- POSTGRES_URL=${POSTGRES_URL}
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
restart: "no"
|
||||
|
||||
web:
|
||||
image: ghcr.io/kanbn/kan:latest
|
||||
container_name: kan-web
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "${WEB_PORT:-3000}:3000"
|
||||
networks:
|
||||
- kan-network
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
NEXT_PUBLIC_BASE_URL: http://localhost:3000
|
||||
BETTER_AUTH_SECRET: your_auth_secret
|
||||
POSTGRES_URL: postgresql://kan:your_postgres_password@postgres:5432/kan_db
|
||||
NEXT_PUBLIC_ALLOW_CREDENTIALS: true
|
||||
- NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL}
|
||||
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
|
||||
- POSTGRES_URL=${POSTGRES_URL}
|
||||
- NEXT_PUBLIC_ALLOW_CREDENTIALS=true
|
||||
depends_on:
|
||||
- postgres
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
restart: unless-stopped
|
||||
|
||||
postgres:
|
||||
image: postgres:15
|
||||
container_name: kan-db
|
||||
environment:
|
||||
POSTGRES_DB: kan_db
|
||||
POSTGRES_USER: kan
|
||||
POSTGRES_PASSWORD: your_postgres_password
|
||||
- POSTGRES_DB=kan_db
|
||||
- POSTGRES_USER=kan
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
ports:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
- kan_postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U kan -d kan_db"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- kan-network
|
||||
@@ -101,23 +123,23 @@ volumes:
|
||||
kan_postgres_data:
|
||||
```
|
||||
|
||||
2. Start the containers in detached mode:
|
||||
3. Start the containers in detached mode:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
3. Access Kan at http://localhost:3000
|
||||
The `migrate` service will automatically run database migrations before the web service starts. The application will be available at http://localhost:3000 (or the port specified in `WEB_PORT`).
|
||||
|
||||
The application will be running in the background. You can manage the containers using these commands:
|
||||
**Managing containers:**
|
||||
|
||||
- To stop the containers: `docker compose down`
|
||||
- To view logs: `docker compose logs -f`
|
||||
- To view logs for a specific service: `docker compose logs -f web` or `docker compose logs -f migrate`
|
||||
- To restart the containers: `docker compose restart`
|
||||
- To rebuild after code changes: `docker compose up -d --build`
|
||||
|
||||
For the complete Docker Compose configuration, see [docker-compose.yml](./docker-compose.yml) in the repository.
|
||||
|
||||
> **Note**: The Docker Compose configuration shown above is a minimal example. For a complete setup with all features (email, OAuth, file uploads, etc.), you'll need to create a `.env` file with the required environment variables. See the Environment Variables section below for the full list of available options.
|
||||
For the complete Docker Compose configuration with all optional features, see [docker-compose.yml](./docker-compose.yml) in the repository.
|
||||
|
||||
## Local Development 🧑💻
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ checksums:
|
||||
0xWkkH/placeholders/boardCount/0: 8cc7c9ba5252e9266c6eb8434fae00f3
|
||||
0xWkkH/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
0xWkkH/translation: 72358c550bd1a99fcb6e8952f0f947ef
|
||||
yndBF%2B/translation: 9fb995d992256a9db7822d430ad75ba0
|
||||
yndBF%2B/message: 9fb995d992256a9db7822d430ad75ba0
|
||||
yndBF%2B/placeholders/projectCount/0: 23257c47018d21aeae42cf5bd0aa9932
|
||||
yndBF%2B/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
9lFfqv/message: 6cb28ff89203e2eca3fdd69396dd00d6
|
||||
9lFfqv/origin/0/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
9lFfqv/translation: 6cb28ff89203e2eca3fdd69396dd00d6
|
||||
@@ -81,6 +85,9 @@ checksums:
|
||||
7L01XJ/message: c46571856723b03262fd33f511116298
|
||||
7L01XJ/origin/0/0: feacdaf2791aaddec128f463ffa2e807
|
||||
7L01XJ/translation: c46571856723b03262fd33f511116298
|
||||
F6pfE9/message: 3e1ec025c4a50830bbb9ad57a176630a
|
||||
F6pfE9/origin/0/0: 4b563046ba98abb3777fb1c3560866aa
|
||||
F6pfE9/translation: 3e1ec025c4a50830bbb9ad57a176630a
|
||||
XJOV1Y/message: 1948763de8e531483a798b68195e297e
|
||||
XJOV1Y/origin/0/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
XJOV1Y/origin/1/0: 9c8b544f5db130cd7c5eda9064ba3957
|
||||
@@ -208,6 +215,12 @@ checksums:
|
||||
WnEwDO/message: 2959fd276248208b65cb27ed46b20135
|
||||
WnEwDO/origin/0/0: d6f5120f072a821219608624f361384e
|
||||
WnEwDO/translation: 2959fd276248208b65cb27ed46b20135
|
||||
j1%2BHPc/translation: baf4c3cd580291f41458f9ed28102c49
|
||||
j1%2BHPc/message: baf4c3cd580291f41458f9ed28102c49
|
||||
j1%2BHPc/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
Dz63YI/translation: 8e43abcd6e039b51084937e4829f58ad
|
||||
Dz63YI/message: 8e43abcd6e039b51084937e4829f58ad
|
||||
Dz63YI/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
WmPhYW/message: 0aa3973b860c1faf8d9123aebf567e40
|
||||
WmPhYW/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
WmPhYW/translation: 0aa3973b860c1faf8d9123aebf567e40
|
||||
@@ -245,6 +258,12 @@ checksums:
|
||||
yb%2Ffjw/message: 2f5426445800ecd5a3102aac940d459c
|
||||
yb%2Ffjw/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
yb%2Ffjw/translation: 2f5426445800ecd5a3102aac940d459c
|
||||
aKJHG%2B/message: 63de765f7fd7bc5238a3e36532306b6b
|
||||
aKJHG%2B/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
aKJHG%2B/translation: 63de765f7fd7bc5238a3e36532306b6b
|
||||
TdfEV7/message: cf5127ecfd7e43a35466a1ba5fe16450
|
||||
TdfEV7/origin/0/0: 4b563046ba98abb3777fb1c3560866aa
|
||||
TdfEV7/translation: cf5127ecfd7e43a35466a1ba5fe16450
|
||||
lo8xBK/message: f9b67026c5ef86ac4d5944380d571961
|
||||
lo8xBK/placeholders/entityLabel/0: 5745fa1af326b9ac2b140cbbef90cdeb
|
||||
lo8xBK/origin/0/0: 68450df287fb46ea629e818732c1291a
|
||||
@@ -332,6 +351,9 @@ checksums:
|
||||
YhvWXb/origin/0/0: ff4a160eca5f8da4f075fd1dd6061fa6
|
||||
YhvWXb/origin/1/0: dbad0c8d7863cb41f5495264f82e7081
|
||||
YhvWXb/translation: 336a8c70a91adc49c15266167ee84cc0
|
||||
i0ZMQl/message: f739058266a2cb6a3d7cca14de09c69a
|
||||
i0ZMQl/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
i0ZMQl/translation: f739058266a2cb6a3d7cca14de09c69a
|
||||
wewm3j/message: 985c0177744ec56d8dac84f66ec284ca
|
||||
wewm3j/origin/0/0: bcd95e286f12800a3e7ee0a71feb3ca5
|
||||
wewm3j/translation: 985c0177744ec56d8dac84f66ec284ca
|
||||
@@ -344,6 +366,9 @@ checksums:
|
||||
XNxYxq/message: b0e6a79e1751b734e1060a1034a893d6
|
||||
XNxYxq/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
XNxYxq/translation: b0e6a79e1751b734e1060a1034a893d6
|
||||
tbNcu4/message: 3817a16b436504bb8d96ca5ee62078cc
|
||||
tbNcu4/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
tbNcu4/translation: 3817a16b436504bb8d96ca5ee62078cc
|
||||
Xid3K6/message: ba018946ffdf85e55d701a9c27595b4d
|
||||
Xid3K6/origin/0/0: 2e937f7560901c3de71a592b4fd80f34
|
||||
Xid3K6/translation: ba018946ffdf85e55d701a9c27595b4d
|
||||
@@ -368,6 +393,9 @@ checksums:
|
||||
8TveY%2B/origin/0/0: 94d3e20c29bb517dd394711d7524e478
|
||||
8TveY%2B/origin/1/0: c0b59968b2b234167c488a05cc38710b
|
||||
8TveY%2B/translation: 8fff51c5872e051beb9b718336665e80
|
||||
0RE1AJ/message: c9a1699f5037acf87aaa6515d0f16910
|
||||
0RE1AJ/origin/0/0: f78c0a7870158f5dab5216bcd6092e49
|
||||
0RE1AJ/translation: c9a1699f5037acf87aaa6515d0f16910
|
||||
ZDo4HN/message: 736332f2e4488609e42d2be8547d296e
|
||||
ZDo4HN/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
ZDo4HN/translation: 736332f2e4488609e42d2be8547d296e
|
||||
@@ -600,13 +628,21 @@ checksums:
|
||||
479pdJ/message: a0d2935d7b63f8dd19d7c0de47524416
|
||||
479pdJ/origin/0/0: 0627e0040ca4939c9a57349e98c51797
|
||||
479pdJ/translation: a0d2935d7b63f8dd19d7c0de47524416
|
||||
iSLIjg/translation: 8778ee245078a8be4a2ce855c8c56edc
|
||||
iSLIjg/message: 8778ee245078a8be4a2ce855c8c56edc
|
||||
iSLIjg/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
3jod3l/translation: 71ca612e433a9ed61ccfbfe1cc87c78b
|
||||
3jod3l/message: 71ca612e433a9ed61ccfbfe1cc87c78b
|
||||
3jod3l/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
nk7caK/message: 4440a0b9e387ef7136e3958e7a089213
|
||||
nk7caK/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
nk7caK/origin/1/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
nk7caK/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
nk7caK/translation: 4440a0b9e387ef7136e3958e7a089213
|
||||
sDLCvT/message: 033c5dcdb059ccb634aef7fe63f2f45d
|
||||
sDLCvT/origin/0/0: d77eb1f90f2fa86a55181629d88d237a
|
||||
sDLCvT/translation: 033c5dcdb059ccb634aef7fe63f2f45d
|
||||
MCIXdZ/translation: ad3738e5eeabcebd3478cdc2545f543f
|
||||
MCIXdZ/message: ad3738e5eeabcebd3478cdc2545f543f
|
||||
MCIXdZ/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
5eZwRW/message: 84a510a7485f43e43f2191bd161171d7
|
||||
5eZwRW/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
5eZwRW/translation: 84a510a7485f43e43f2191bd161171d7
|
||||
@@ -808,6 +844,9 @@ checksums:
|
||||
f8fH8W/message: 991b75727b6784c1a063a7462b76186d
|
||||
f8fH8W/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
f8fH8W/translation: 991b75727b6784c1a063a7462b76186d
|
||||
Odv3J6/translation: f3cc49ba2dc3f9c33917f8a749d68bf5
|
||||
Odv3J6/message: f3cc49ba2dc3f9c33917f8a749d68bf5
|
||||
Odv3J6/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
YBBifR/message: a2dd737d133887d34504728c7e7f05e3
|
||||
YBBifR/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
YBBifR/translation: a2dd737d133887d34504728c7e7f05e3
|
||||
@@ -957,6 +996,9 @@ checksums:
|
||||
55xJ%2FO/message: ebecb5c1b72ba4b063117241f5ba4f2d
|
||||
55xJ%2FO/origin/0/0: 0627e0040ca4939c9a57349e98c51797
|
||||
55xJ%2FO/translation: ebecb5c1b72ba4b063117241f5ba4f2d
|
||||
yhLUU8/translation: e879ffdeccbe5b00fa7ece09114d149f
|
||||
yhLUU8/message: e879ffdeccbe5b00fa7ece09114d149f
|
||||
yhLUU8/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
cji2nM/message: cbedc3f3213dfc4fdc8b7503ae1a5cd6
|
||||
cji2nM/origin/0/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
cji2nM/translation: cbedc3f3213dfc4fdc8b7503ae1a5cd6
|
||||
@@ -972,6 +1014,9 @@ checksums:
|
||||
9s9O5h/message: 0aec9bd8170bc84f5ea5c9a47c52ed26
|
||||
9s9O5h/origin/0/0: 83911e3eacbad4583e2b1647a784d154
|
||||
9s9O5h/translation: 0aec9bd8170bc84f5ea5c9a47c52ed26
|
||||
gQ%2F02p/translation: 08e8dfeafa38796abcdcc258917428d6
|
||||
gQ%2F02p/message: 08e8dfeafa38796abcdcc258917428d6
|
||||
gQ%2F02p/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
lKAvEd/message: a8766853864eddc480113778a708871b
|
||||
lKAvEd/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
lKAvEd/translation: a8766853864eddc480113778a708871b
|
||||
@@ -1137,7 +1182,14 @@ checksums:
|
||||
7hktsm/translation: 8e5e7bd026b5bec46bbfdce02ab9e0b8
|
||||
RkXlPZ/message: 6e1cf3c00fa6fbe24afcc78ea3b5f3e4
|
||||
RkXlPZ/origin/0/0: 98e2302d0d8d12ce65c4140b87450673
|
||||
RkXlPZ/origin/1/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
RkXlPZ/translation: 6e1cf3c00fa6fbe24afcc78ea3b5f3e4
|
||||
PVT7q7/translation: 8fa30040ec891db0b5b7d893786514ab
|
||||
PVT7q7/message: 8fa30040ec891db0b5b7d893786514ab
|
||||
PVT7q7/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
"%2FbBVaD/translation": 79b9a6153d695ff0175aa804b1c0286b
|
||||
"%2FbBVaD/message": 79b9a6153d695ff0175aa804b1c0286b
|
||||
"%2FbBVaD/origin/0/0": 9d4260644f1a12f41d6b72574eeb111c
|
||||
7eMo%2BU/message: 6251589da1964d55afabdfd64c84c335
|
||||
7eMo%2BU/origin/0/0: 6cda8b872e4902cbc0191d9375adf4ef
|
||||
7eMo%2BU/translation: 6251589da1964d55afabdfd64c84c335
|
||||
@@ -1210,9 +1262,11 @@ checksums:
|
||||
l3s5ri/translation: 348b8ab981de5b7f1fca6d7302263bbd
|
||||
2MPcep/message: 7e749df6f068b9cdf1055ea38c9a80af
|
||||
2MPcep/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
2MPcep/origin/1/0: 3c57a918258af4b44c187f58d203345f
|
||||
2MPcep/translation: 7e749df6f068b9cdf1055ea38c9a80af
|
||||
BEVzjL/message: bcec1f271c82ddffc91ebc22021b03cb
|
||||
BEVzjL/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
BEVzjL/origin/1/0: 3c57a918258af4b44c187f58d203345f
|
||||
BEVzjL/translation: bcec1f271c82ddffc91ebc22021b03cb
|
||||
rRM7r0/message: d66d13649f81342f8b3a4f3b54370c20
|
||||
rRM7r0/origin/0/0: d77eb1f90f2fa86a55181629d88d237a
|
||||
@@ -1500,6 +1554,9 @@ checksums:
|
||||
"%2FglL9Q/placeholders/0/0": 07bd981d42ffe27ee81d1dffa7dc0d43
|
||||
"%2FglL9Q/origin/0/0": f78c0a7870158f5dab5216bcd6092e49
|
||||
"%2FglL9Q/translation": a7a95e1dfdb4396da9e2be0e27f42323
|
||||
tlhgDC/message: b96a6f8fa3267ec01e68e61656382b2e
|
||||
tlhgDC/origin/0/0: f78c0a7870158f5dab5216bcd6092e49
|
||||
tlhgDC/translation: b96a6f8fa3267ec01e68e61656382b2e
|
||||
Eg99Sc/message: f718c896810da3612202887f9a4374fa
|
||||
Eg99Sc/origin/0/0: d96af8a06c2e38a72238bcd16e426859
|
||||
Eg99Sc/translation: f718c896810da3612202887f9a4374fa
|
||||
@@ -1524,6 +1581,9 @@ checksums:
|
||||
fvLNDy/message: f18ee3d7230cc33b68bd17b429d1d442
|
||||
fvLNDy/origin/0/0: fc0c18a095a68277a0f90a115942683b
|
||||
fvLNDy/translation: f18ee3d7230cc33b68bd17b429d1d442
|
||||
i30J2U/translation: 8b7ec59963fb26e13948600c55c8de1d
|
||||
i30J2U/message: 8b7ec59963fb26e13948600c55c8de1d
|
||||
i30J2U/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
ERpq2P/message: 5db6294712528cd897b15ae36f4fd834
|
||||
ERpq2P/placeholders/debouncedQuery/0: 8471823afb4210cf564ca0d8bef9dd66
|
||||
ERpq2P/origin/0/0: 89a76a14edc1c0b7876d79d7571bb8fb
|
||||
@@ -1679,40 +1739,41 @@ checksums:
|
||||
tyHiOa/origin/10/0: fc0c18a095a68277a0f90a115942683b
|
||||
tyHiOa/origin/11/0: fc0c18a095a68277a0f90a115942683b
|
||||
tyHiOa/origin/12/0: 3c57a918258af4b44c187f58d203345f
|
||||
tyHiOa/origin/13/0: 3a89a46ac678e34dc8eb687b07a4ad4b
|
||||
tyHiOa/origin/14/0: a31bf5b0f5348dedcad98939fcf7f93f
|
||||
tyHiOa/origin/13/0: 3c57a918258af4b44c187f58d203345f
|
||||
tyHiOa/origin/14/0: 3a89a46ac678e34dc8eb687b07a4ad4b
|
||||
tyHiOa/origin/15/0: a31bf5b0f5348dedcad98939fcf7f93f
|
||||
tyHiOa/origin/16/0: 6e60e97757a446204985b5c4374ed66d
|
||||
tyHiOa/origin/17/0: d2cacb98e99d5163eff64f9c4c9cbb47
|
||||
tyHiOa/origin/18/0: b2059fa4b8b99cc10440da26475b234c
|
||||
tyHiOa/origin/19/0: 2a382c1cdf010f01a8e95c3e05f6df53
|
||||
tyHiOa/origin/20/0: d55f532bb5ae247e3a018978be0da463
|
||||
tyHiOa/origin/21/0: 4b4f55c033add8db69178563832227c6
|
||||
tyHiOa/origin/22/0: 2201bf679c663a732d7f1b3c3ce3897f
|
||||
tyHiOa/origin/23/0: 27ce4b16f6ada6ca35ac8d1adff329c5
|
||||
tyHiOa/origin/24/0: a55c169a847bdde3b119eeb97e202c30
|
||||
tyHiOa/origin/25/0: faa852a0c0e3c81fe948e394029c1ba5
|
||||
tyHiOa/origin/26/0: a2dd1fc876bd42b9db7ca7aaa57ac5e2
|
||||
tyHiOa/origin/27/0: e59eec882722e98169cc27f545facfe7
|
||||
tyHiOa/origin/28/0: b1f4eb6768222ea825703105f6014486
|
||||
tyHiOa/origin/29/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
tyHiOa/origin/16/0: a31bf5b0f5348dedcad98939fcf7f93f
|
||||
tyHiOa/origin/17/0: 6e60e97757a446204985b5c4374ed66d
|
||||
tyHiOa/origin/18/0: d2cacb98e99d5163eff64f9c4c9cbb47
|
||||
tyHiOa/origin/19/0: b2059fa4b8b99cc10440da26475b234c
|
||||
tyHiOa/origin/20/0: 2a382c1cdf010f01a8e95c3e05f6df53
|
||||
tyHiOa/origin/21/0: d55f532bb5ae247e3a018978be0da463
|
||||
tyHiOa/origin/22/0: 4b4f55c033add8db69178563832227c6
|
||||
tyHiOa/origin/23/0: 2201bf679c663a732d7f1b3c3ce3897f
|
||||
tyHiOa/origin/24/0: 27ce4b16f6ada6ca35ac8d1adff329c5
|
||||
tyHiOa/origin/25/0: a55c169a847bdde3b119eeb97e202c30
|
||||
tyHiOa/origin/26/0: faa852a0c0e3c81fe948e394029c1ba5
|
||||
tyHiOa/origin/27/0: a2dd1fc876bd42b9db7ca7aaa57ac5e2
|
||||
tyHiOa/origin/28/0: e59eec882722e98169cc27f545facfe7
|
||||
tyHiOa/origin/29/0: b1f4eb6768222ea825703105f6014486
|
||||
tyHiOa/origin/30/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
tyHiOa/origin/31/0: 68450df287fb46ea629e818732c1291a
|
||||
tyHiOa/origin/32/0: afee530613110e248ffde6b56872ebed
|
||||
tyHiOa/origin/31/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
tyHiOa/origin/32/0: 68450df287fb46ea629e818732c1291a
|
||||
tyHiOa/origin/33/0: afee530613110e248ffde6b56872ebed
|
||||
tyHiOa/origin/34/0: afee530613110e248ffde6b56872ebed
|
||||
tyHiOa/origin/35/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
tyHiOa/origin/35/0: afee530613110e248ffde6b56872ebed
|
||||
tyHiOa/origin/36/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
tyHiOa/origin/37/0: 7493592314bc3b96ad96127a949ba1ba
|
||||
tyHiOa/origin/38/0: 03c00909b41be01231cd3e843c8ee44e
|
||||
tyHiOa/origin/39/0: 5c60161e173f5eae9276d8e4c70b4ebb
|
||||
tyHiOa/origin/40/0: 83911e3eacbad4583e2b1647a784d154
|
||||
tyHiOa/origin/41/0: d465da67c0a870d198eb7f313569c137
|
||||
tyHiOa/origin/42/0: 33bf266228f835e12c0bfb0e5efb3be9
|
||||
tyHiOa/origin/43/0: ff48991e314b0b3e989a4dac59860fd5
|
||||
tyHiOa/origin/44/0: 30791e26a172d47d3cb0693e82679246
|
||||
tyHiOa/origin/45/0: dbad0c8d7863cb41f5495264f82e7081
|
||||
tyHiOa/origin/46/0: 0dccc39d0debbf3e089cb6d292de762b
|
||||
tyHiOa/origin/37/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
tyHiOa/origin/38/0: 7493592314bc3b96ad96127a949ba1ba
|
||||
tyHiOa/origin/39/0: 03c00909b41be01231cd3e843c8ee44e
|
||||
tyHiOa/origin/40/0: 5c60161e173f5eae9276d8e4c70b4ebb
|
||||
tyHiOa/origin/41/0: 83911e3eacbad4583e2b1647a784d154
|
||||
tyHiOa/origin/42/0: d465da67c0a870d198eb7f313569c137
|
||||
tyHiOa/origin/43/0: 33bf266228f835e12c0bfb0e5efb3be9
|
||||
tyHiOa/origin/44/0: ff48991e314b0b3e989a4dac59860fd5
|
||||
tyHiOa/origin/45/0: 30791e26a172d47d3cb0693e82679246
|
||||
tyHiOa/origin/46/0: dbad0c8d7863cb41f5495264f82e7081
|
||||
tyHiOa/origin/47/0: 0dccc39d0debbf3e089cb6d292de762b
|
||||
tyHiOa/translation: 21ffcf0b00e7cd7b64f7454a95762e1d
|
||||
PZCqeW/message: 325dea6dd0348a27a6818db2c1340c98
|
||||
PZCqeW/origin/0/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
@@ -1893,6 +1954,7 @@ checksums:
|
||||
K3iLeO/translation: e3bf6f95419169f460fb6918a0afc512
|
||||
wgNoIs/message: eedc7cdb02de467c15dc418a066a77f2
|
||||
wgNoIs/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
wgNoIs/origin/1/0: 3c57a918258af4b44c187f58d203345f
|
||||
wgNoIs/translation: eedc7cdb02de467c15dc418a066a77f2
|
||||
rYUZIe/message: c7b0ec447415ff62856803a4d7838bd6
|
||||
rYUZIe/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
@@ -2052,6 +2114,12 @@ checksums:
|
||||
nhMhRr/message: 07edd8c50685a52c0969d711df26d768
|
||||
nhMhRr/origin/0/0: 1fd8ccf586705354bcae6e1186108fc7
|
||||
nhMhRr/translation: 07edd8c50685a52c0969d711df26d768
|
||||
NcFrgC/message: bd15a7b3d8b4bce18cd42682ea1ec164
|
||||
NcFrgC/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
NcFrgC/translation: bd15a7b3d8b4bce18cd42682ea1ec164
|
||||
C6gv54/message: 1573c77059bc92df17e661befda8d9b7
|
||||
C6gv54/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
C6gv54/translation: 1573c77059bc92df17e661befda8d9b7
|
||||
jlB2RY/message: 67a76bf346ab4b48563269e9d941a64a
|
||||
jlB2RY/origin/0/0: 0627e0040ca4939c9a57349e98c51797
|
||||
jlB2RY/translation: 67a76bf346ab4b48563269e9d941a64a
|
||||
@@ -2128,6 +2196,9 @@ checksums:
|
||||
4gAX8s/message: 29dea3e0b6238874f8c7a27619df8e36
|
||||
4gAX8s/origin/0/0: 634473ef965836871efe40875a36b6ab
|
||||
4gAX8s/translation: 29dea3e0b6238874f8c7a27619df8e36
|
||||
L5WQLg/translation: 38a978eab728978612d1dee8bdeb915b
|
||||
L5WQLg/message: 38a978eab728978612d1dee8bdeb915b
|
||||
L5WQLg/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
eEQyz%2B/message: 0d3bac559c71ec4b8734f9f212320de5
|
||||
eEQyz%2B/origin/0/0: d77eb1f90f2fa86a55181629d88d237a
|
||||
eEQyz%2B/translation: 0d3bac559c71ec4b8734f9f212320de5
|
||||
@@ -2249,6 +2320,9 @@ checksums:
|
||||
TFv5tM/message: 4f2240aeff6f7275feb33ca3f608e48c
|
||||
TFv5tM/origin/0/0: 7493592314bc3b96ad96127a949ba1ba
|
||||
TFv5tM/translation: 4f2240aeff6f7275feb33ca3f608e48c
|
||||
It4%2FFS/message: ae1527c2765592f13980acb66997e570
|
||||
It4%2FFS/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
It4%2FFS/translation: ae1527c2765592f13980acb66997e570
|
||||
E8zYtd/message: b683cc07092348c1e75dba40b1262b85
|
||||
E8zYtd/placeholders/0/0: 182720128698512d43d1bf43824cd7f8
|
||||
E8zYtd/origin/0/0: 1d6b5f88cdad160a67842f6b65387448
|
||||
@@ -2541,12 +2615,24 @@ checksums:
|
||||
tca56%2F/message: 19d84e934877efc0fef285ff3d6e7849
|
||||
tca56%2F/origin/0/0: 12c1fab543c8848bcb10107d47336736
|
||||
tca56%2F/translation: 19d84e934877efc0fef285ff3d6e7849
|
||||
HcT8J4/translation: 19478f9152e6879c9c029198e635b44d
|
||||
HcT8J4/message: 19478f9152e6879c9c029198e635b44d
|
||||
HcT8J4/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
AdxYds/translation: a265e2d3b01efd3fe04ac251d2ff6afc
|
||||
AdxYds/message: a265e2d3b01efd3fe04ac251d2ff6afc
|
||||
AdxYds/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
PELbXB/translation: 6984aed03bbcd94041c5dd20f62e56ed
|
||||
PELbXB/message: 6984aed03bbcd94041c5dd20f62e56ed
|
||||
PELbXB/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
Ozt2vv/message: 8f730f68d52b7efa727aa0784282ebcb
|
||||
Ozt2vv/origin/0/0: 0627e0040ca4939c9a57349e98c51797
|
||||
Ozt2vv/translation: 8f730f68d52b7efa727aa0784282ebcb
|
||||
"%2FtOdd2/message": 099e1780348cd7bf617721344371a430
|
||||
"%2FtOdd2/origin/0/0": 03c00909b41be01231cd3e843c8ee44e
|
||||
"%2FtOdd2/translation": 099e1780348cd7bf617721344371a430
|
||||
"%2BjbXzb/translation": c07e27183a52361fc05b919c2a3f5c1f
|
||||
"%2BjbXzb/message": c07e27183a52361fc05b919c2a3f5c1f
|
||||
"%2BjbXzb/origin/0/0": 3c57a918258af4b44c187f58d203345f
|
||||
CJWDTP/message: 126aeeb73f7e4cad338056e4c933f39b
|
||||
CJWDTP/origin/0/0: 9d4260644f1a12f41d6b72574eeb111c
|
||||
CJWDTP/translation: 126aeeb73f7e4cad338056e4c933f39b
|
||||
|
||||
@@ -463,13 +463,6 @@ export default function Editor({
|
||||
StarterKit.configure({
|
||||
heading: disableHeadings ? false : undefined,
|
||||
}),
|
||||
Markdown,
|
||||
Placeholder.configure({
|
||||
placeholder: readOnly
|
||||
? ""
|
||||
: placeholder ??
|
||||
t`Add description... (type '/' to open commands or '@' to mention)`,
|
||||
}),
|
||||
Link.configure({
|
||||
openOnClick: true,
|
||||
HTMLAttributes: {
|
||||
@@ -479,6 +472,14 @@ export default function Editor({
|
||||
},
|
||||
validate: (href) => /^https?:\/\//.test(href),
|
||||
autolink: true,
|
||||
linkOnPaste: true,
|
||||
}),
|
||||
Markdown,
|
||||
Placeholder.configure({
|
||||
placeholder: readOnly
|
||||
? ""
|
||||
: placeholder ??
|
||||
t`Add description... (type '/' to open commands or '@' to mention)`,
|
||||
}),
|
||||
SlashCommands.configure({
|
||||
commandItems: getCommandItems(disableHeadings),
|
||||
|
||||
@@ -19,6 +19,7 @@ interface UsePermissionsResult {
|
||||
canCreateBoard: boolean;
|
||||
canEditBoard: boolean;
|
||||
canDeleteBoard: boolean;
|
||||
canArchiveBoard: boolean;
|
||||
canViewComment: boolean;
|
||||
canCreateComment: boolean;
|
||||
canEditComment: boolean;
|
||||
@@ -33,7 +34,7 @@ interface UsePermissionsResult {
|
||||
export function usePermissions(): UsePermissionsResult {
|
||||
// Check if WorkspaceProvider is available (for public board views, it may not be)
|
||||
const workspaceContext = useContext(WorkspaceContext);
|
||||
|
||||
|
||||
// If WorkspaceProvider is not available, return safe defaults
|
||||
if (!workspaceContext) {
|
||||
const emptyPermissions: UsePermissionsResult = {
|
||||
@@ -51,6 +52,7 @@ export function usePermissions(): UsePermissionsResult {
|
||||
canCreateBoard: false,
|
||||
canEditBoard: false,
|
||||
canDeleteBoard: false,
|
||||
canArchiveBoard: false,
|
||||
canViewComment: false,
|
||||
canCreateComment: false,
|
||||
canEditComment: false,
|
||||
@@ -95,6 +97,7 @@ export function usePermissions(): UsePermissionsResult {
|
||||
canCreateBoard: hasPermission("board:create"),
|
||||
canEditBoard: hasPermission("board:edit"),
|
||||
canDeleteBoard: hasPermission("board:delete"),
|
||||
canArchiveBoard: hasPermission("board:edit"),
|
||||
canViewComment: hasPermission("comment:view"),
|
||||
canCreateComment: hasPermission("comment:create"),
|
||||
canEditComment: hasPermission("comment:edit"),
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"0": ["isTemplate ? \"Templates\" : \"Boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 40]],
|
||||
"origin": [["src/views/boards/index.tsx", 53]],
|
||||
"translation": "{0}"
|
||||
},
|
||||
"JArWcF": {
|
||||
@@ -33,8 +33,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/card/index.tsx", 309]
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/card/index.tsx", 308]
|
||||
],
|
||||
"translation": "{0} | {1}"
|
||||
},
|
||||
@@ -44,7 +44,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 56]],
|
||||
"translation": "{0} wurde zu deinen Favoriten hinzugefügt."
|
||||
},
|
||||
"bDI6VI": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 55]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 57]],
|
||||
"translation": "{0} wurde aus deinen Favoriten entfernt."
|
||||
},
|
||||
"CJukzS": {
|
||||
@@ -80,9 +80,18 @@
|
||||
"boardCount": ["boardCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 299]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 489]],
|
||||
"translation": "{boardCount, plural, one {Board importieren (1)} other {Boards importieren ({boardCount})}}"
|
||||
},
|
||||
"yndBF+": {
|
||||
"message": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}",
|
||||
"placeholders": {
|
||||
"projectCount": ["projectCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 341]],
|
||||
"translation": "{projectCount, plural, one {Projekt importieren (1)} other {Projekte importieren ({projectCount})}}"
|
||||
},
|
||||
"9lFfqv": {
|
||||
"message": "/month",
|
||||
"placeholders": {},
|
||||
@@ -185,12 +194,19 @@
|
||||
"origin": [["src/providers/keyboard-shortcuts.tsx", 56]],
|
||||
"translation": "Aktionen"
|
||||
},
|
||||
"F6pfE9": {
|
||||
"message": "Active",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 26]],
|
||||
"translation": "Aktiv"
|
||||
},
|
||||
"XJOV1Y": {
|
||||
"message": "Activity",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 447],
|
||||
["src/views/card/index.tsx", 446],
|
||||
["src/views/public/board/CardModal.tsx", 189]
|
||||
],
|
||||
"translation": "Aktivität"
|
||||
@@ -246,7 +262,7 @@
|
||||
"message": "Add description... (type '/' to open commands or '@' to mention)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/Editor.tsx", 471]],
|
||||
"origin": [["src/components/Editor.tsx", 482]],
|
||||
"translation": "Beschreibung hinzufügen... (‚/' für Befehle oder ‚@' zum Erwähnen eingeben)"
|
||||
},
|
||||
"abUZlY": {
|
||||
@@ -280,7 +296,7 @@
|
||||
"message": "Add to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 93]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 122]],
|
||||
"translation": "Zu Favoriten hinzufügen"
|
||||
},
|
||||
"bmXKoX": {
|
||||
@@ -368,7 +384,7 @@
|
||||
"message": "Added to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 51]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 53]],
|
||||
"translation": "Zu Favoriten hinzugefügt"
|
||||
},
|
||||
"14Xi3Z": {
|
||||
@@ -482,14 +498,28 @@
|
||||
"message": "Already have an account? <0><1>Sign in</1></0>",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 88]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 90]],
|
||||
"translation": "Haben Sie bereits ein Konto? <0><1>Anmelden</1></0>"
|
||||
},
|
||||
"j1+HPc": {
|
||||
"message": "An error occurred while connecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 107]],
|
||||
"translation": "Beim Verbinden Ihres GitHub-Kontos ist ein Fehler aufgetreten."
|
||||
},
|
||||
"Dz63YI": {
|
||||
"message": "An error occurred while disconnecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 130]],
|
||||
"translation": "Beim Trennen Ihres GitHub-Kontos ist ein Fehler aufgetreten."
|
||||
},
|
||||
"WmPhYW": {
|
||||
"message": "An error occurred while disconnecting your Trello account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 61]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 87]],
|
||||
"translation": "Beim Trennen Ihres Trello-Kontos ist ein Fehler aufgetreten."
|
||||
},
|
||||
"ZXSPJt": {
|
||||
@@ -574,6 +604,20 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 46]],
|
||||
"translation": "Genehmigung"
|
||||
},
|
||||
"aKJHG+": {
|
||||
"message": "Archive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Board archivieren"
|
||||
},
|
||||
"TdfEV7": {
|
||||
"message": "Archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 27]],
|
||||
"translation": "Archiviert"
|
||||
},
|
||||
"lo8xBK": {
|
||||
"message": "Are you sure want to remove {entityLabel}?",
|
||||
"placeholders": {
|
||||
@@ -770,7 +814,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/card/index.tsx", 309],
|
||||
["src/views/card/index.tsx", 308],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
"translation": "Board"
|
||||
@@ -785,6 +829,13 @@
|
||||
],
|
||||
"translation": "Board-Analyse"
|
||||
},
|
||||
"i0ZMQl": {
|
||||
"message": "Board archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Board archiviert"
|
||||
},
|
||||
"wewm3j": {
|
||||
"message": "Board name cannot exceed 100 characters",
|
||||
"placeholders": {},
|
||||
@@ -815,6 +866,13 @@
|
||||
],
|
||||
"translation": "Board-Vorlagen"
|
||||
},
|
||||
"tbNcu4": {
|
||||
"message": "Board unarchived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Board wiederhergestellt"
|
||||
},
|
||||
"Xid3K6": {
|
||||
"message": "Board URL can only contain letters, numbers, and hyphens",
|
||||
"placeholders": {},
|
||||
@@ -873,6 +931,13 @@
|
||||
],
|
||||
"translation": "Boards"
|
||||
},
|
||||
"0RE1AJ": {
|
||||
"message": "Boards you archive will appear here.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Boards, die du archivierst, werden hier angezeigt."
|
||||
},
|
||||
"ZDo4HN": {
|
||||
"message": "Brainstorming",
|
||||
"placeholders": {},
|
||||
@@ -1163,7 +1228,7 @@
|
||||
"message": "Card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 309]],
|
||||
"origin": [["src/views/card/index.tsx", 308]],
|
||||
"translation": "Karte"
|
||||
},
|
||||
"fEY2vP": {
|
||||
@@ -1171,8 +1236,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 355],
|
||||
["src/views/card/index.tsx", 392]
|
||||
["src/views/card/index.tsx", 354],
|
||||
["src/views/card/index.tsx", 391]
|
||||
],
|
||||
"translation": "Karte nicht gefunden"
|
||||
},
|
||||
@@ -1237,7 +1302,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 43],
|
||||
["src/views/auth/signup/index.tsx", 69]
|
||||
["src/views/auth/signup/index.tsx", 71]
|
||||
],
|
||||
"translation": "Überprüfen Sie Ihren Posteingang"
|
||||
},
|
||||
@@ -1305,7 +1370,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 48],
|
||||
["src/views/auth/signup/index.tsx", 74]
|
||||
["src/views/auth/signup/index.tsx", 76]
|
||||
],
|
||||
"translation": "Klicken Sie auf den Link, den wir an {magicLinkRecipient} gesendet haben, um sich anzumelden."
|
||||
},
|
||||
@@ -1314,7 +1379,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 346],
|
||||
["src/views/card/index.tsx", 345],
|
||||
["src/views/members/components/EditMemberPermissionsModal.tsx", 172],
|
||||
["src/views/settings/components/NewApiKeyModal.tsx", 136]
|
||||
],
|
||||
@@ -1431,14 +1496,25 @@
|
||||
],
|
||||
"translation": "Bestätigen Sie Ihr neues Passwort"
|
||||
},
|
||||
"iSLIjg": {
|
||||
"message": "Connect",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Verbinden"
|
||||
},
|
||||
"3jod3l": {
|
||||
"message": "Connect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 212]],
|
||||
"translation": "GitHub verbinden"
|
||||
},
|
||||
"nk7caK": {
|
||||
"message": "Connect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 157],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 93]
|
||||
],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 162]],
|
||||
"translation": "Trello verbinden"
|
||||
},
|
||||
"sDLCvT": {
|
||||
@@ -1448,11 +1524,18 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 122]],
|
||||
"translation": "Verbinden Sie Ihre bevorzugten Tools, um Ihren Workflow zu optimieren."
|
||||
},
|
||||
"MCIXdZ": {
|
||||
"message": "Connect your GitHub account to import projects.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 191]],
|
||||
"translation": "Verbinden Sie Ihr GitHub-Konto, um Projekte zu importieren."
|
||||
},
|
||||
"5eZwRW": {
|
||||
"message": "Connect your Trello account to import boards.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 149]],
|
||||
"translation": "Verbinden Sie Ihr Trello-Konto, um Boards zu importieren."
|
||||
},
|
||||
"jfC/xh": {
|
||||
@@ -1612,8 +1695,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/BoardsList.tsx", 79],
|
||||
["src/views/boards/index.tsx", 28]
|
||||
["src/views/boards/components/BoardsList.tsx", 80],
|
||||
["src/views/boards/index.tsx", 41]
|
||||
],
|
||||
"translation": "Neue {0} erstellen"
|
||||
},
|
||||
@@ -1835,7 +1918,7 @@
|
||||
"message": "Delete board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Board löschen"
|
||||
},
|
||||
"nabda1": {
|
||||
@@ -1863,7 +1946,7 @@
|
||||
"message": "Delete template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Vorlage löschen"
|
||||
},
|
||||
"kYu0eF": {
|
||||
@@ -1916,11 +1999,18 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 45]],
|
||||
"translation": "Design"
|
||||
},
|
||||
"Odv3J6": {
|
||||
"message": "Disconnect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 223]],
|
||||
"translation": "GitHub trennen"
|
||||
},
|
||||
"YBBifR": {
|
||||
"message": "Disconnect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 108]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 177]],
|
||||
"translation": "Trello trennen"
|
||||
},
|
||||
"1sRmLC": {
|
||||
@@ -2079,7 +2169,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/BoardDropdown.tsx", 84],
|
||||
["src/views/board/components/BoardDropdown.tsx", 102],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 116]
|
||||
],
|
||||
"translation": "Board-URL bearbeiten"
|
||||
@@ -2265,6 +2355,13 @@
|
||||
],
|
||||
"translation": "Fehler beim Ändern des Passworts"
|
||||
},
|
||||
"yhLUU8": {
|
||||
"message": "Error connecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 106]],
|
||||
"translation": "Fehler beim Verbinden von GitHub"
|
||||
},
|
||||
"cji2nM": {
|
||||
"message": "Error creating invite link",
|
||||
"placeholders": {},
|
||||
@@ -2304,11 +2401,18 @@
|
||||
],
|
||||
"translation": "Fehler beim Löschen des Arbeitsbereichs"
|
||||
},
|
||||
"gQ/02p": {
|
||||
"message": "Error disconnecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 129]],
|
||||
"translation": "Fehler beim Trennen von GitHub"
|
||||
},
|
||||
"lKAvEd": {
|
||||
"message": "Error disconnecting Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 60]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 86]],
|
||||
"translation": "Fehler beim Trennen von Trello"
|
||||
},
|
||||
"rarRW/": {
|
||||
@@ -2622,7 +2726,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 69],
|
||||
["src/views/auth/signup/index.tsx", 71],
|
||||
["src/views/home/components/Cta.tsx", 61],
|
||||
["src/views/home/components/Header.tsx", 106],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 29],
|
||||
@@ -2647,7 +2751,7 @@
|
||||
"0": ["isTemplate ? \"template\" : \"board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 65]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Legen Sie los, indem Sie ein neues {0} erstellen"
|
||||
},
|
||||
"zC8Whw": {
|
||||
@@ -2689,9 +2793,26 @@
|
||||
"message": "GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/home/components/Footer.tsx", 37]],
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 37],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 186]
|
||||
],
|
||||
"translation": "GitHub"
|
||||
},
|
||||
"PVT7q7": {
|
||||
"message": "GitHub connected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 99]],
|
||||
"translation": "GitHub verbunden"
|
||||
},
|
||||
"/bBVaD": {
|
||||
"message": "GitHub disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 122]],
|
||||
"translation": "GitHub getrennt"
|
||||
},
|
||||
"7eMo+U": {
|
||||
"message": "Go Home",
|
||||
"placeholders": {},
|
||||
@@ -2863,21 +2984,27 @@
|
||||
"message": "Import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 60]],
|
||||
"origin": [["src/views/boards/index.tsx", 73]],
|
||||
"translation": "Importieren"
|
||||
},
|
||||
"2MPcep": {
|
||||
"message": "Import complete",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 191]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 229],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 381]
|
||||
],
|
||||
"translation": "Import abgeschlossen"
|
||||
},
|
||||
"BEVzjL": {
|
||||
"message": "Import failed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 204]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 242],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 394]
|
||||
],
|
||||
"translation": "Import fehlgeschlagen"
|
||||
},
|
||||
"rRM7r0": {
|
||||
@@ -3299,7 +3426,7 @@
|
||||
"message": "Make template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 73]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Vorlage erstellen"
|
||||
},
|
||||
"IDvohQ": {
|
||||
@@ -3432,7 +3559,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 82],
|
||||
["src/views/boards/index.tsx", 95],
|
||||
["src/views/home/components/Features.tsx", 73]
|
||||
],
|
||||
"translation": "Neu"
|
||||
@@ -3471,7 +3598,7 @@
|
||||
"message": "New import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 322]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 513]],
|
||||
"translation": "Neuer Import"
|
||||
},
|
||||
"n1GRql": {
|
||||
@@ -3550,9 +3677,16 @@
|
||||
"0": ["isTemplate ? \"templates\" : \"boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 62]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Keine {0}"
|
||||
},
|
||||
"tlhgDC": {
|
||||
"message": "No archived boards",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Keine archivierten Boards"
|
||||
},
|
||||
"Eg99Sc": {
|
||||
"message": "No authentication methods are currently available",
|
||||
"placeholders": {},
|
||||
@@ -3564,7 +3698,7 @@
|
||||
"message": "No boards found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 242]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 432]],
|
||||
"translation": "Keine Boards gefunden"
|
||||
},
|
||||
"OpNhRn": {
|
||||
@@ -3609,6 +3743,13 @@
|
||||
"origin": [["src/views/board/index.tsx", 527]],
|
||||
"translation": "Es wurden noch keine Listen erstellt"
|
||||
},
|
||||
"i30J2U": {
|
||||
"message": "No projects found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 283]],
|
||||
"translation": "Keine Projekte gefunden"
|
||||
},
|
||||
"ERpq2P": {
|
||||
"message": "No results found for \"{debouncedQuery}\".",
|
||||
"placeholders": {
|
||||
@@ -3963,7 +4104,7 @@
|
||||
["src/components/DeleteLabelConfirmation.tsx", 26],
|
||||
["src/components/FeedbackModal.tsx", 41],
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/board/components/BoardDropdown.tsx", 63],
|
||||
["src/views/board/components/BoardDropdown.tsx", 65],
|
||||
["src/views/board/components/NewCardForm.tsx", 184],
|
||||
["src/views/board/components/NewListForm.tsx", 79],
|
||||
["src/views/board/components/NewTemplateForm.tsx", 61],
|
||||
@@ -3972,7 +4113,8 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 181],
|
||||
["src/views/board/index.tsx", 237],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 205],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 69],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 97],
|
||||
@@ -4178,7 +4320,7 @@
|
||||
"message": "Remove from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 92]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 121]],
|
||||
"translation": "Aus Favoriten entfernen"
|
||||
},
|
||||
"99VIgC": {
|
||||
@@ -4232,7 +4374,7 @@
|
||||
"message": "Removed from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 52]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"translation": "Aus Favoriten entfernt"
|
||||
},
|
||||
"YVT40D": {
|
||||
@@ -4426,14 +4568,17 @@
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 274]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 315],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 464]
|
||||
],
|
||||
"translation": "Alle auswählen"
|
||||
},
|
||||
"rYUZIe": {
|
||||
"message": "Select source",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 157]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Quelle auswählen"
|
||||
},
|
||||
"ppaRWv": {
|
||||
@@ -4520,7 +4665,7 @@
|
||||
"message": "Settings | Integrations",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 69]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 138]],
|
||||
"translation": "Einstellungen | Integrationen"
|
||||
},
|
||||
"F/FPk/": {
|
||||
@@ -4570,8 +4715,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 34],
|
||||
["src/views/auth/signup/index.tsx", 59]
|
||||
["src/views/auth/signup/index.tsx", 36],
|
||||
["src/views/auth/signup/index.tsx", 61]
|
||||
],
|
||||
"translation": "Registrieren | kan.bn"
|
||||
},
|
||||
@@ -4579,14 +4724,14 @@
|
||||
"message": "Sign up disabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 44]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 46]],
|
||||
"translation": "Registrierung deaktiviert"
|
||||
},
|
||||
"s6iE/c": {
|
||||
"message": "Sign up is currently disabled. Please try again later.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 47]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 49]],
|
||||
"translation": "Die Registrierung ist derzeit deaktiviert. Bitte versuchen Sie es später erneut."
|
||||
},
|
||||
"6FDocz": {
|
||||
@@ -4809,6 +4954,20 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 34]],
|
||||
"translation": "Vielen Dank für Ihr Feedback!"
|
||||
},
|
||||
"NcFrgC": {
|
||||
"message": "The board has been archived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 46]],
|
||||
"translation": "Das Board wurde archiviert."
|
||||
},
|
||||
"C6gv54": {
|
||||
"message": "The board has been unarchived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Das Board wurde wiederhergestellt."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5001,6 +5160,13 @@
|
||||
"origin": [["src/views/home/components/Header.tsx", 114]],
|
||||
"translation": "Menü umschalten"
|
||||
},
|
||||
"L5WQLg": {
|
||||
"message": "Token is required",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 19]],
|
||||
"translation": "Token ist erforderlich"
|
||||
},
|
||||
"eEQyz+": {
|
||||
"message": "Track all card changes with detailed activity history.",
|
||||
"placeholders": {},
|
||||
@@ -5014,7 +5180,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 218],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 73]
|
||||
["src/views/settings/IntegrationsSettings.tsx", 142]
|
||||
],
|
||||
"translation": "Trello"
|
||||
},
|
||||
@@ -5022,7 +5188,7 @@
|
||||
"message": "Trello disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 53]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 79]],
|
||||
"translation": "Trello getrennt"
|
||||
},
|
||||
"kxEs5t": {
|
||||
@@ -5196,7 +5362,7 @@
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 62]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 64]],
|
||||
"translation": "Board konnte nicht aktualisiert werden"
|
||||
},
|
||||
"XpcjLO": {
|
||||
@@ -5292,6 +5458,13 @@
|
||||
"origin": [["src/views/members/index.tsx", 65]],
|
||||
"translation": "Rolle konnte nicht aktualisiert werden"
|
||||
},
|
||||
"It4/FS": {
|
||||
"message": "Unarchive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Board wiederherstellen"
|
||||
},
|
||||
"E8zYtd": {
|
||||
"message": "unassigned <0>{0}</0> from the card",
|
||||
"placeholders": {
|
||||
@@ -5671,7 +5844,7 @@
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 46],
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
["src/views/public/boards/index.tsx", 65]
|
||||
@@ -5883,9 +6056,9 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 474],
|
||||
["src/views/board/index.tsx", 532],
|
||||
["src/views/boards/components/BoardsList.tsx", 70],
|
||||
["src/views/boards/index.tsx", 46],
|
||||
["src/views/boards/index.tsx", 67]
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
],
|
||||
"translation": "Sie haben keine Berechtigung"
|
||||
},
|
||||
@@ -5951,7 +6124,7 @@
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 192]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 382]],
|
||||
"translation": "Ihre Boards wurden importiert."
|
||||
},
|
||||
"LqWW5F": {
|
||||
@@ -5968,6 +6141,27 @@
|
||||
"origin": [["src/views/card/components/AttachmentUpload.tsx", 46]],
|
||||
"translation": "Ihre Datei wurde erfolgreich hochgeladen."
|
||||
},
|
||||
"HcT8J4": {
|
||||
"message": "Your GitHub account has been connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 100]],
|
||||
"translation": "Ihr GitHub-Konto wurde verbunden."
|
||||
},
|
||||
"AdxYds": {
|
||||
"message": "Your GitHub account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 123]],
|
||||
"translation": "Ihr GitHub-Konto wurde getrennt."
|
||||
},
|
||||
"PELbXB": {
|
||||
"message": "Your GitHub account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 220]],
|
||||
"translation": "Ihr GitHub-Konto ist verbunden."
|
||||
},
|
||||
"Ozt2vv": {
|
||||
"message": "Your password has been changed.",
|
||||
"placeholders": {},
|
||||
@@ -5984,18 +6178,25 @@
|
||||
"origin": [["src/views/settings/components/Avatar.tsx", 190]],
|
||||
"translation": "Ihr Profilbild wurde aktualisiert."
|
||||
},
|
||||
"+jbXzb": {
|
||||
"message": "Your projects have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 230]],
|
||||
"translation": "Ihre Projekte wurden importiert."
|
||||
},
|
||||
"CJWDTP": {
|
||||
"message": "Your Trello account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 54]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"translation": "Ihr Trello-Konto wurde getrennt."
|
||||
},
|
||||
"WRsbHO": {
|
||||
"message": "Your Trello account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 102]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 171]],
|
||||
"translation": "Ihr Trello-Konto ist verbunden."
|
||||
},
|
||||
"25fAUC": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -34,7 +34,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
40
|
||||
53
|
||||
]
|
||||
],
|
||||
"translation": "{0}"
|
||||
@@ -55,11 +55,11 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
35
|
||||
48
|
||||
],
|
||||
[
|
||||
"src/views/card/index.tsx",
|
||||
309
|
||||
308
|
||||
]
|
||||
],
|
||||
"translation": "{0} | {1}"
|
||||
@@ -75,7 +75,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
54
|
||||
56
|
||||
]
|
||||
],
|
||||
"translation": "{0} has been added to your favorites."
|
||||
@@ -91,7 +91,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
55
|
||||
57
|
||||
]
|
||||
],
|
||||
"translation": "{0} has been removed from your favorites."
|
||||
@@ -139,11 +139,27 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
299
|
||||
489
|
||||
]
|
||||
],
|
||||
"translation": "{boardCount, plural, one {Import board (1)} other {Import boards ({boardCount})}}"
|
||||
},
|
||||
"yndBF+": {
|
||||
"message": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}",
|
||||
"placeholders": {
|
||||
"projectCount": [
|
||||
"projectCount"
|
||||
]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
341
|
||||
]
|
||||
],
|
||||
"translation": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}"
|
||||
},
|
||||
"9lFfqv": {
|
||||
"message": "/month",
|
||||
"placeholders": {},
|
||||
@@ -312,6 +328,18 @@
|
||||
],
|
||||
"translation": "Actions"
|
||||
},
|
||||
"F6pfE9": {
|
||||
"message": "Active",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
26
|
||||
]
|
||||
],
|
||||
"translation": "Active"
|
||||
},
|
||||
"XJOV1Y": {
|
||||
"message": "Activity",
|
||||
"placeholders": {},
|
||||
@@ -319,7 +347,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/card/index.tsx",
|
||||
447
|
||||
446
|
||||
],
|
||||
[
|
||||
"src/views/public/board/CardModal.tsx",
|
||||
@@ -411,7 +439,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/components/Editor.tsx",
|
||||
471
|
||||
482
|
||||
]
|
||||
],
|
||||
"translation": "Add description... (type '/' to open commands or '@' to mention)"
|
||||
@@ -467,7 +495,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
93
|
||||
122
|
||||
]
|
||||
],
|
||||
"translation": "Add to favorites"
|
||||
@@ -622,7 +650,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
51
|
||||
53
|
||||
]
|
||||
],
|
||||
"translation": "Added to favorites"
|
||||
@@ -813,11 +841,35 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/auth/signup/index.tsx",
|
||||
88
|
||||
90
|
||||
]
|
||||
],
|
||||
"translation": "Already have an account? <0><1>Sign in</1></0>"
|
||||
},
|
||||
"j1+HPc": {
|
||||
"message": "An error occurred while connecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
107
|
||||
]
|
||||
],
|
||||
"translation": "An error occurred while connecting your GitHub account."
|
||||
},
|
||||
"Dz63YI": {
|
||||
"message": "An error occurred while disconnecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
130
|
||||
]
|
||||
],
|
||||
"translation": "An error occurred while disconnecting your GitHub account."
|
||||
},
|
||||
"WmPhYW": {
|
||||
"message": "An error occurred while disconnecting your Trello account.",
|
||||
"placeholders": {},
|
||||
@@ -825,7 +877,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
61
|
||||
87
|
||||
]
|
||||
],
|
||||
"translation": "An error occurred while disconnecting your Trello account."
|
||||
@@ -966,6 +1018,30 @@
|
||||
],
|
||||
"translation": "Approval"
|
||||
},
|
||||
"aKJHG+": {
|
||||
"message": "Archive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
111
|
||||
]
|
||||
],
|
||||
"translation": "Archive board"
|
||||
},
|
||||
"TdfEV7": {
|
||||
"message": "Archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
27
|
||||
]
|
||||
],
|
||||
"translation": "Archived"
|
||||
},
|
||||
"lo8xBK": {
|
||||
"message": "Are you sure want to remove {entityLabel}?",
|
||||
"placeholders": {
|
||||
@@ -1289,7 +1365,7 @@
|
||||
],
|
||||
[
|
||||
"src/views/card/index.tsx",
|
||||
309
|
||||
308
|
||||
],
|
||||
[
|
||||
"src/views/public/board/index.tsx",
|
||||
@@ -1314,6 +1390,18 @@
|
||||
],
|
||||
"translation": "Board analytics"
|
||||
},
|
||||
"i0ZMQl": {
|
||||
"message": "Board archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
44
|
||||
]
|
||||
],
|
||||
"translation": "Board archived"
|
||||
},
|
||||
"wewm3j": {
|
||||
"message": "Board name cannot exceed 100 characters",
|
||||
"placeholders": {},
|
||||
@@ -1362,6 +1450,18 @@
|
||||
],
|
||||
"translation": "Board templates"
|
||||
},
|
||||
"tbNcu4": {
|
||||
"message": "Board unarchived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
44
|
||||
]
|
||||
],
|
||||
"translation": "Board unarchived"
|
||||
},
|
||||
"Xid3K6": {
|
||||
"message": "Board URL can only contain letters, numbers, and hyphens",
|
||||
"placeholders": {},
|
||||
@@ -1458,6 +1558,18 @@
|
||||
],
|
||||
"translation": "Boards"
|
||||
},
|
||||
"0RE1AJ": {
|
||||
"message": "Boards you archive will appear here.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/BoardsList.tsx",
|
||||
66
|
||||
]
|
||||
],
|
||||
"translation": "Boards you archive will appear here."
|
||||
},
|
||||
"ZDo4HN": {
|
||||
"message": "Brainstorming",
|
||||
"placeholders": {},
|
||||
@@ -1949,7 +2061,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/card/index.tsx",
|
||||
309
|
||||
308
|
||||
]
|
||||
],
|
||||
"translation": "Card"
|
||||
@@ -1961,11 +2073,11 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/card/index.tsx",
|
||||
355
|
||||
354
|
||||
],
|
||||
[
|
||||
"src/views/card/index.tsx",
|
||||
392
|
||||
391
|
||||
]
|
||||
],
|
||||
"translation": "Card not found"
|
||||
@@ -2077,7 +2189,7 @@
|
||||
],
|
||||
[
|
||||
"src/views/auth/signup/index.tsx",
|
||||
69
|
||||
71
|
||||
]
|
||||
],
|
||||
"translation": "Check your inbox"
|
||||
@@ -2177,7 +2289,7 @@
|
||||
],
|
||||
[
|
||||
"src/views/auth/signup/index.tsx",
|
||||
74
|
||||
76
|
||||
]
|
||||
],
|
||||
"translation": "Click on the link we've sent to {magicLinkRecipient} to sign in."
|
||||
@@ -2189,7 +2301,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/card/index.tsx",
|
||||
346
|
||||
345
|
||||
],
|
||||
[
|
||||
"src/views/members/components/EditMemberPermissionsModal.tsx",
|
||||
@@ -2386,18 +2498,38 @@
|
||||
],
|
||||
"translation": "Confirm your new password"
|
||||
},
|
||||
"iSLIjg": {
|
||||
"message": "Connect",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
195
|
||||
]
|
||||
],
|
||||
"translation": "Connect"
|
||||
},
|
||||
"3jod3l": {
|
||||
"message": "Connect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
212
|
||||
]
|
||||
],
|
||||
"translation": "Connect GitHub"
|
||||
},
|
||||
"nk7caK": {
|
||||
"message": "Connect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
157
|
||||
],
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
93
|
||||
162
|
||||
]
|
||||
],
|
||||
"translation": "Connect Trello"
|
||||
@@ -2414,6 +2546,18 @@
|
||||
],
|
||||
"translation": "Connect your favorite tools to streamline your workflow."
|
||||
},
|
||||
"MCIXdZ": {
|
||||
"message": "Connect your GitHub account to import projects.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
191
|
||||
]
|
||||
],
|
||||
"translation": "Connect your GitHub account to import projects."
|
||||
},
|
||||
"5eZwRW": {
|
||||
"message": "Connect your Trello account to import boards.",
|
||||
"placeholders": {},
|
||||
@@ -2421,7 +2565,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
80
|
||||
149
|
||||
]
|
||||
],
|
||||
"translation": "Connect your Trello account to import boards."
|
||||
@@ -2693,11 +2837,11 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/BoardsList.tsx",
|
||||
79
|
||||
80
|
||||
],
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
28
|
||||
41
|
||||
]
|
||||
],
|
||||
"translation": "Create new {0}"
|
||||
@@ -3077,7 +3221,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
104
|
||||
133
|
||||
]
|
||||
],
|
||||
"translation": "Delete board"
|
||||
@@ -3125,7 +3269,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
104
|
||||
133
|
||||
]
|
||||
],
|
||||
"translation": "Delete template"
|
||||
@@ -3218,6 +3362,18 @@
|
||||
],
|
||||
"translation": "Design"
|
||||
},
|
||||
"Odv3J6": {
|
||||
"message": "Disconnect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
223
|
||||
]
|
||||
],
|
||||
"translation": "Disconnect GitHub"
|
||||
},
|
||||
"YBBifR": {
|
||||
"message": "Disconnect Trello",
|
||||
"placeholders": {},
|
||||
@@ -3225,7 +3381,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
108
|
||||
177
|
||||
]
|
||||
],
|
||||
"translation": "Disconnect Trello"
|
||||
@@ -3513,7 +3669,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
84
|
||||
102
|
||||
],
|
||||
[
|
||||
"src/views/board/components/UpdateBoardSlugForm.tsx",
|
||||
@@ -3814,6 +3970,18 @@
|
||||
],
|
||||
"translation": "Error Changing Password"
|
||||
},
|
||||
"yhLUU8": {
|
||||
"message": "Error connecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
106
|
||||
]
|
||||
],
|
||||
"translation": "Error connecting GitHub"
|
||||
},
|
||||
"cji2nM": {
|
||||
"message": "Error creating invite link",
|
||||
"placeholders": {},
|
||||
@@ -3874,6 +4042,18 @@
|
||||
],
|
||||
"translation": "Error deleting workspace"
|
||||
},
|
||||
"gQ/02p": {
|
||||
"message": "Error disconnecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
129
|
||||
]
|
||||
],
|
||||
"translation": "Error disconnecting GitHub"
|
||||
},
|
||||
"lKAvEd": {
|
||||
"message": "Error disconnecting Trello",
|
||||
"placeholders": {},
|
||||
@@ -3881,7 +4061,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
60
|
||||
86
|
||||
]
|
||||
],
|
||||
"translation": "Error disconnecting Trello"
|
||||
@@ -4409,7 +4589,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/auth/signup/index.tsx",
|
||||
69
|
||||
71
|
||||
],
|
||||
[
|
||||
"src/views/home/components/Cta.tsx",
|
||||
@@ -4461,7 +4641,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/BoardsList.tsx",
|
||||
65
|
||||
66
|
||||
]
|
||||
],
|
||||
"translation": "Get started by creating a new {0}"
|
||||
@@ -4534,10 +4714,38 @@
|
||||
[
|
||||
"src/views/home/components/Footer.tsx",
|
||||
37
|
||||
],
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
186
|
||||
]
|
||||
],
|
||||
"translation": "GitHub"
|
||||
},
|
||||
"PVT7q7": {
|
||||
"message": "GitHub connected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
99
|
||||
]
|
||||
],
|
||||
"translation": "GitHub connected"
|
||||
},
|
||||
"/bBVaD": {
|
||||
"message": "GitHub disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
122
|
||||
]
|
||||
],
|
||||
"translation": "GitHub disconnected"
|
||||
},
|
||||
"7eMo+U": {
|
||||
"message": "Go Home",
|
||||
"placeholders": {},
|
||||
@@ -4821,7 +5029,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
60
|
||||
73
|
||||
]
|
||||
],
|
||||
"translation": "Import"
|
||||
@@ -4833,7 +5041,11 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
191
|
||||
229
|
||||
],
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
381
|
||||
]
|
||||
],
|
||||
"translation": "Import complete"
|
||||
@@ -4845,7 +5057,11 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
204
|
||||
242
|
||||
],
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
394
|
||||
]
|
||||
],
|
||||
"translation": "Import failed"
|
||||
@@ -5557,7 +5773,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
73
|
||||
91
|
||||
]
|
||||
],
|
||||
"translation": "Make template"
|
||||
@@ -5792,7 +6008,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
82
|
||||
95
|
||||
],
|
||||
[
|
||||
"src/views/home/components/Features.tsx",
|
||||
@@ -5860,7 +6076,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
322
|
||||
513
|
||||
]
|
||||
],
|
||||
"translation": "New import"
|
||||
@@ -5988,11 +6204,23 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/BoardsList.tsx",
|
||||
62
|
||||
63
|
||||
]
|
||||
],
|
||||
"translation": "No {0}"
|
||||
},
|
||||
"tlhgDC": {
|
||||
"message": "No archived boards",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/BoardsList.tsx",
|
||||
63
|
||||
]
|
||||
],
|
||||
"translation": "No archived boards"
|
||||
},
|
||||
"Eg99Sc": {
|
||||
"message": "No authentication methods are currently available",
|
||||
"placeholders": {},
|
||||
@@ -6012,7 +6240,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
242
|
||||
432
|
||||
]
|
||||
],
|
||||
"translation": "No boards found"
|
||||
@@ -6089,6 +6317,18 @@
|
||||
],
|
||||
"translation": "No lists have been created yet"
|
||||
},
|
||||
"i30J2U": {
|
||||
"message": "No projects found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
283
|
||||
]
|
||||
],
|
||||
"translation": "No projects found"
|
||||
},
|
||||
"ERpq2P": {
|
||||
"message": "No results found for \"{debouncedQuery}\".",
|
||||
"placeholders": {
|
||||
@@ -6672,7 +6912,7 @@
|
||||
],
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
63
|
||||
65
|
||||
],
|
||||
[
|
||||
"src/views/board/components/NewCardForm.tsx",
|
||||
@@ -6708,7 +6948,11 @@
|
||||
],
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
205
|
||||
243
|
||||
],
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
395
|
||||
],
|
||||
[
|
||||
"src/views/card/components/AttachmentThumbnails.tsx",
|
||||
@@ -7144,7 +7388,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
92
|
||||
121
|
||||
]
|
||||
],
|
||||
"translation": "Remove from favorites"
|
||||
@@ -7239,7 +7483,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
52
|
||||
54
|
||||
]
|
||||
],
|
||||
"translation": "Removed from favorites"
|
||||
@@ -7563,7 +7807,11 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
274
|
||||
315
|
||||
],
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
464
|
||||
]
|
||||
],
|
||||
"translation": "Select all"
|
||||
@@ -7575,7 +7823,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
157
|
||||
195
|
||||
]
|
||||
],
|
||||
"translation": "Select source"
|
||||
@@ -7723,7 +7971,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
69
|
||||
138
|
||||
]
|
||||
],
|
||||
"translation": "Settings | Integrations"
|
||||
@@ -7807,11 +8055,11 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/auth/signup/index.tsx",
|
||||
34
|
||||
36
|
||||
],
|
||||
[
|
||||
"src/views/auth/signup/index.tsx",
|
||||
59
|
||||
61
|
||||
]
|
||||
],
|
||||
"translation": "Sign up | kan.bn"
|
||||
@@ -7823,7 +8071,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/auth/signup/index.tsx",
|
||||
44
|
||||
46
|
||||
]
|
||||
],
|
||||
"translation": "Sign up disabled"
|
||||
@@ -7835,7 +8083,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/auth/signup/index.tsx",
|
||||
47
|
||||
49
|
||||
]
|
||||
],
|
||||
"translation": "Sign up is currently disabled. Please try again later."
|
||||
@@ -8200,6 +8448,30 @@
|
||||
],
|
||||
"translation": "Thank you for your feedback!"
|
||||
},
|
||||
"NcFrgC": {
|
||||
"message": "The board has been archived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
46
|
||||
]
|
||||
],
|
||||
"translation": "The board has been archived."
|
||||
},
|
||||
"C6gv54": {
|
||||
"message": "The board has been unarchived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
47
|
||||
]
|
||||
],
|
||||
"translation": "The board has been unarchived."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -8504,6 +8776,18 @@
|
||||
],
|
||||
"translation": "Toggle menu"
|
||||
},
|
||||
"L5WQLg": {
|
||||
"message": "Token is required",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
19
|
||||
]
|
||||
],
|
||||
"translation": "Token is required"
|
||||
},
|
||||
"eEQyz+": {
|
||||
"message": "Track all card changes with detailed activity history.",
|
||||
"placeholders": {},
|
||||
@@ -8527,7 +8811,7 @@
|
||||
],
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
73
|
||||
142
|
||||
]
|
||||
],
|
||||
"translation": "Trello"
|
||||
@@ -8539,7 +8823,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
53
|
||||
79
|
||||
]
|
||||
],
|
||||
"translation": "Trello disconnected"
|
||||
@@ -8827,7 +9111,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
62
|
||||
64
|
||||
]
|
||||
],
|
||||
"translation": "Unable to update board"
|
||||
@@ -8988,6 +9272,18 @@
|
||||
],
|
||||
"translation": "Unable to update role"
|
||||
},
|
||||
"It4/FS": {
|
||||
"message": "Unarchive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/board/components/BoardDropdown.tsx",
|
||||
111
|
||||
]
|
||||
],
|
||||
"translation": "Unarchive board"
|
||||
},
|
||||
"E8zYtd": {
|
||||
"message": "unassigned <0>{0}</0> from the card",
|
||||
"placeholders": {
|
||||
@@ -9659,7 +9955,7 @@
|
||||
],
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
35
|
||||
48
|
||||
],
|
||||
[
|
||||
"src/views/members/index.tsx",
|
||||
@@ -10011,15 +10307,15 @@
|
||||
],
|
||||
[
|
||||
"src/views/boards/components/BoardsList.tsx",
|
||||
70
|
||||
71
|
||||
],
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
46
|
||||
59
|
||||
],
|
||||
[
|
||||
"src/views/boards/index.tsx",
|
||||
67
|
||||
80
|
||||
]
|
||||
],
|
||||
"translation": "You don't have permission"
|
||||
@@ -10127,7 +10423,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
192
|
||||
382
|
||||
]
|
||||
],
|
||||
"translation": "Your boards have been imported."
|
||||
@@ -10156,6 +10452,42 @@
|
||||
],
|
||||
"translation": "Your file has been uploaded successfully."
|
||||
},
|
||||
"HcT8J4": {
|
||||
"message": "Your GitHub account has been connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
100
|
||||
]
|
||||
],
|
||||
"translation": "Your GitHub account has been connected."
|
||||
},
|
||||
"AdxYds": {
|
||||
"message": "Your GitHub account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
123
|
||||
]
|
||||
],
|
||||
"translation": "Your GitHub account has been disconnected."
|
||||
},
|
||||
"PELbXB": {
|
||||
"message": "Your GitHub account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
220
|
||||
]
|
||||
],
|
||||
"translation": "Your GitHub account is connected."
|
||||
},
|
||||
"Ozt2vv": {
|
||||
"message": "Your password has been changed.",
|
||||
"placeholders": {},
|
||||
@@ -10180,6 +10512,18 @@
|
||||
],
|
||||
"translation": "Your profile image has been updated."
|
||||
},
|
||||
"+jbXzb": {
|
||||
"message": "Your projects have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
[
|
||||
"src/views/boards/components/ImportBoardsForm.tsx",
|
||||
230
|
||||
]
|
||||
],
|
||||
"translation": "Your projects have been imported."
|
||||
},
|
||||
"CJWDTP": {
|
||||
"message": "Your Trello account has been disconnected.",
|
||||
"placeholders": {},
|
||||
@@ -10187,7 +10531,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
54
|
||||
80
|
||||
]
|
||||
],
|
||||
"translation": "Your Trello account has been disconnected."
|
||||
@@ -10199,7 +10543,7 @@
|
||||
"origin": [
|
||||
[
|
||||
"src/views/settings/IntegrationsSettings.tsx",
|
||||
102
|
||||
171
|
||||
]
|
||||
],
|
||||
"translation": "Your Trello account is connected."
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -19,7 +19,7 @@
|
||||
"0": ["isTemplate ? \"Templates\" : \"Boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 40]],
|
||||
"origin": [["src/views/boards/index.tsx", 53]],
|
||||
"translation": "{0}"
|
||||
},
|
||||
"JArWcF": {
|
||||
@@ -33,8 +33,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/card/index.tsx", 309]
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/card/index.tsx", 308]
|
||||
],
|
||||
"translation": "{0} | {1}"
|
||||
},
|
||||
@@ -44,7 +44,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 56]],
|
||||
"translation": "{0} se ha añadido a tus favoritos."
|
||||
},
|
||||
"bDI6VI": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 55]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 57]],
|
||||
"translation": "{0} se ha eliminado de tus favoritos."
|
||||
},
|
||||
"CJukzS": {
|
||||
@@ -80,9 +80,18 @@
|
||||
"boardCount": ["boardCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 299]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 489]],
|
||||
"translation": "{boardCount, plural, one {Importar tablero (1)} other {Importar tableros ({boardCount})}}"
|
||||
},
|
||||
"yndBF+": {
|
||||
"message": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}",
|
||||
"placeholders": {
|
||||
"projectCount": ["projectCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 341]],
|
||||
"translation": "{projectCount, plural, one {Importar proyecto (1)} other {Importar proyectos ({projectCount})}}"
|
||||
},
|
||||
"9lFfqv": {
|
||||
"message": "/month",
|
||||
"placeholders": {},
|
||||
@@ -185,12 +194,19 @@
|
||||
"origin": [["src/providers/keyboard-shortcuts.tsx", 56]],
|
||||
"translation": "Acciones"
|
||||
},
|
||||
"F6pfE9": {
|
||||
"message": "Active",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 26]],
|
||||
"translation": "Activo"
|
||||
},
|
||||
"XJOV1Y": {
|
||||
"message": "Activity",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 447],
|
||||
["src/views/card/index.tsx", 446],
|
||||
["src/views/public/board/CardModal.tsx", 189]
|
||||
],
|
||||
"translation": "Actividad"
|
||||
@@ -246,7 +262,7 @@
|
||||
"message": "Add description... (type '/' to open commands or '@' to mention)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/Editor.tsx", 471]],
|
||||
"origin": [["src/components/Editor.tsx", 482]],
|
||||
"translation": "Añadir descripción... (escribe '/' para abrir comandos o '@' para mencionar)"
|
||||
},
|
||||
"abUZlY": {
|
||||
@@ -280,7 +296,7 @@
|
||||
"message": "Add to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 93]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 122]],
|
||||
"translation": "Añadir a favoritos"
|
||||
},
|
||||
"bmXKoX": {
|
||||
@@ -368,7 +384,7 @@
|
||||
"message": "Added to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 51]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 53]],
|
||||
"translation": "Añadido a favoritos"
|
||||
},
|
||||
"14Xi3Z": {
|
||||
@@ -482,14 +498,28 @@
|
||||
"message": "Already have an account? <0><1>Sign in</1></0>",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 88]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 90]],
|
||||
"translation": "¿Ya tienes una cuenta? <0><1>Inicia sesión</1></0>"
|
||||
},
|
||||
"j1+HPc": {
|
||||
"message": "An error occurred while connecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 107]],
|
||||
"translation": "Ocurrió un error al conectar tu cuenta de GitHub."
|
||||
},
|
||||
"Dz63YI": {
|
||||
"message": "An error occurred while disconnecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 130]],
|
||||
"translation": "Ocurrió un error al desconectar tu cuenta de GitHub."
|
||||
},
|
||||
"WmPhYW": {
|
||||
"message": "An error occurred while disconnecting your Trello account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 61]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 87]],
|
||||
"translation": "Se produjo un error al desconectar tu cuenta de Trello."
|
||||
},
|
||||
"ZXSPJt": {
|
||||
@@ -574,6 +604,20 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 46]],
|
||||
"translation": "Aprobación"
|
||||
},
|
||||
"aKJHG+": {
|
||||
"message": "Archive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Archivar tablero"
|
||||
},
|
||||
"TdfEV7": {
|
||||
"message": "Archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 27]],
|
||||
"translation": "Archivado"
|
||||
},
|
||||
"lo8xBK": {
|
||||
"message": "Are you sure want to remove {entityLabel}?",
|
||||
"placeholders": {
|
||||
@@ -770,7 +814,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/card/index.tsx", 309],
|
||||
["src/views/card/index.tsx", 308],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
"translation": "Tablero"
|
||||
@@ -785,6 +829,13 @@
|
||||
],
|
||||
"translation": "Analíticas del tablero"
|
||||
},
|
||||
"i0ZMQl": {
|
||||
"message": "Board archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Tablero archivado"
|
||||
},
|
||||
"wewm3j": {
|
||||
"message": "Board name cannot exceed 100 characters",
|
||||
"placeholders": {},
|
||||
@@ -815,6 +866,13 @@
|
||||
],
|
||||
"translation": "Plantillas de tablero"
|
||||
},
|
||||
"tbNcu4": {
|
||||
"message": "Board unarchived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Tablero desarchivado"
|
||||
},
|
||||
"Xid3K6": {
|
||||
"message": "Board URL can only contain letters, numbers, and hyphens",
|
||||
"placeholders": {},
|
||||
@@ -873,6 +931,13 @@
|
||||
],
|
||||
"translation": "Tableros"
|
||||
},
|
||||
"0RE1AJ": {
|
||||
"message": "Boards you archive will appear here.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Los tableros que archives aparecerán aquí."
|
||||
},
|
||||
"ZDo4HN": {
|
||||
"message": "Brainstorming",
|
||||
"placeholders": {},
|
||||
@@ -1163,7 +1228,7 @@
|
||||
"message": "Card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 309]],
|
||||
"origin": [["src/views/card/index.tsx", 308]],
|
||||
"translation": "Tarjeta"
|
||||
},
|
||||
"fEY2vP": {
|
||||
@@ -1171,8 +1236,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 355],
|
||||
["src/views/card/index.tsx", 392]
|
||||
["src/views/card/index.tsx", 354],
|
||||
["src/views/card/index.tsx", 391]
|
||||
],
|
||||
"translation": "Tarjeta no encontrada"
|
||||
},
|
||||
@@ -1237,7 +1302,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 43],
|
||||
["src/views/auth/signup/index.tsx", 69]
|
||||
["src/views/auth/signup/index.tsx", 71]
|
||||
],
|
||||
"translation": "Revisa tu bandeja de entrada"
|
||||
},
|
||||
@@ -1305,7 +1370,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 48],
|
||||
["src/views/auth/signup/index.tsx", 74]
|
||||
["src/views/auth/signup/index.tsx", 76]
|
||||
],
|
||||
"translation": "Haz clic en el enlace que hemos enviado a {magicLinkRecipient} para iniciar sesión."
|
||||
},
|
||||
@@ -1314,7 +1379,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 346],
|
||||
["src/views/card/index.tsx", 345],
|
||||
["src/views/members/components/EditMemberPermissionsModal.tsx", 172],
|
||||
["src/views/settings/components/NewApiKeyModal.tsx", 136]
|
||||
],
|
||||
@@ -1431,14 +1496,25 @@
|
||||
],
|
||||
"translation": "Confirma tu nueva contraseña"
|
||||
},
|
||||
"iSLIjg": {
|
||||
"message": "Connect",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Conectar"
|
||||
},
|
||||
"3jod3l": {
|
||||
"message": "Connect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 212]],
|
||||
"translation": "Conectar GitHub"
|
||||
},
|
||||
"nk7caK": {
|
||||
"message": "Connect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 157],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 93]
|
||||
],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 162]],
|
||||
"translation": "Conectar Trello"
|
||||
},
|
||||
"sDLCvT": {
|
||||
@@ -1448,11 +1524,18 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 122]],
|
||||
"translation": "Conecta tus herramientas favoritas para optimizar tu flujo de trabajo."
|
||||
},
|
||||
"MCIXdZ": {
|
||||
"message": "Connect your GitHub account to import projects.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 191]],
|
||||
"translation": "Conecta tu cuenta de GitHub para importar proyectos."
|
||||
},
|
||||
"5eZwRW": {
|
||||
"message": "Connect your Trello account to import boards.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 149]],
|
||||
"translation": "Conecta tu cuenta de Trello para importar tableros."
|
||||
},
|
||||
"jfC/xh": {
|
||||
@@ -1612,8 +1695,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/BoardsList.tsx", 79],
|
||||
["src/views/boards/index.tsx", 28]
|
||||
["src/views/boards/components/BoardsList.tsx", 80],
|
||||
["src/views/boards/index.tsx", 41]
|
||||
],
|
||||
"translation": "Crear nuevo {0}"
|
||||
},
|
||||
@@ -1835,7 +1918,7 @@
|
||||
"message": "Delete board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Eliminar tablero"
|
||||
},
|
||||
"nabda1": {
|
||||
@@ -1863,7 +1946,7 @@
|
||||
"message": "Delete template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Eliminar plantilla"
|
||||
},
|
||||
"kYu0eF": {
|
||||
@@ -1916,11 +1999,18 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 45]],
|
||||
"translation": "Diseño"
|
||||
},
|
||||
"Odv3J6": {
|
||||
"message": "Disconnect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 223]],
|
||||
"translation": "Desconectar GitHub"
|
||||
},
|
||||
"YBBifR": {
|
||||
"message": "Disconnect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 108]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 177]],
|
||||
"translation": "Desconectar Trello"
|
||||
},
|
||||
"1sRmLC": {
|
||||
@@ -2079,7 +2169,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/BoardDropdown.tsx", 84],
|
||||
["src/views/board/components/BoardDropdown.tsx", 102],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 116]
|
||||
],
|
||||
"translation": "Editar URL del tablero"
|
||||
@@ -2265,6 +2355,13 @@
|
||||
],
|
||||
"translation": "Error al cambiar la contraseña"
|
||||
},
|
||||
"yhLUU8": {
|
||||
"message": "Error connecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 106]],
|
||||
"translation": "Error al conectar GitHub"
|
||||
},
|
||||
"cji2nM": {
|
||||
"message": "Error creating invite link",
|
||||
"placeholders": {},
|
||||
@@ -2304,11 +2401,18 @@
|
||||
],
|
||||
"translation": "Error al eliminar el espacio de trabajo"
|
||||
},
|
||||
"gQ/02p": {
|
||||
"message": "Error disconnecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 129]],
|
||||
"translation": "Error al desconectar GitHub"
|
||||
},
|
||||
"lKAvEd": {
|
||||
"message": "Error disconnecting Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 60]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 86]],
|
||||
"translation": "Error al desconectar Trello"
|
||||
},
|
||||
"rarRW/": {
|
||||
@@ -2622,7 +2726,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 69],
|
||||
["src/views/auth/signup/index.tsx", 71],
|
||||
["src/views/home/components/Cta.tsx", 61],
|
||||
["src/views/home/components/Header.tsx", 106],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 29],
|
||||
@@ -2647,7 +2751,7 @@
|
||||
"0": ["isTemplate ? \"template\" : \"board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 65]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Comienza creando un nuevo {0}"
|
||||
},
|
||||
"zC8Whw": {
|
||||
@@ -2689,9 +2793,26 @@
|
||||
"message": "GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/home/components/Footer.tsx", 37]],
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 37],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 186]
|
||||
],
|
||||
"translation": "GitHub"
|
||||
},
|
||||
"PVT7q7": {
|
||||
"message": "GitHub connected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 99]],
|
||||
"translation": "GitHub conectado"
|
||||
},
|
||||
"/bBVaD": {
|
||||
"message": "GitHub disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 122]],
|
||||
"translation": "GitHub desconectado"
|
||||
},
|
||||
"7eMo+U": {
|
||||
"message": "Go Home",
|
||||
"placeholders": {},
|
||||
@@ -2863,21 +2984,27 @@
|
||||
"message": "Import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 60]],
|
||||
"origin": [["src/views/boards/index.tsx", 73]],
|
||||
"translation": "Importar"
|
||||
},
|
||||
"2MPcep": {
|
||||
"message": "Import complete",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 191]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 229],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 381]
|
||||
],
|
||||
"translation": "Importación completada"
|
||||
},
|
||||
"BEVzjL": {
|
||||
"message": "Import failed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 204]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 242],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 394]
|
||||
],
|
||||
"translation": "Importación fallida"
|
||||
},
|
||||
"rRM7r0": {
|
||||
@@ -3299,7 +3426,7 @@
|
||||
"message": "Make template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 73]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Crear plantilla"
|
||||
},
|
||||
"IDvohQ": {
|
||||
@@ -3432,7 +3559,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 82],
|
||||
["src/views/boards/index.tsx", 95],
|
||||
["src/views/home/components/Features.tsx", 73]
|
||||
],
|
||||
"translation": "Nuevo"
|
||||
@@ -3471,7 +3598,7 @@
|
||||
"message": "New import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 322]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 513]],
|
||||
"translation": "Nueva importación"
|
||||
},
|
||||
"n1GRql": {
|
||||
@@ -3550,9 +3677,16 @@
|
||||
"0": ["isTemplate ? \"templates\" : \"boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 62]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "No hay {0}"
|
||||
},
|
||||
"tlhgDC": {
|
||||
"message": "No archived boards",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "No hay tableros archivados"
|
||||
},
|
||||
"Eg99Sc": {
|
||||
"message": "No authentication methods are currently available",
|
||||
"placeholders": {},
|
||||
@@ -3564,7 +3698,7 @@
|
||||
"message": "No boards found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 242]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 432]],
|
||||
"translation": "No se encontraron tableros"
|
||||
},
|
||||
"OpNhRn": {
|
||||
@@ -3609,6 +3743,13 @@
|
||||
"origin": [["src/views/board/index.tsx", 527]],
|
||||
"translation": "Aún no se han creado listas"
|
||||
},
|
||||
"i30J2U": {
|
||||
"message": "No projects found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 283]],
|
||||
"translation": "No se encontraron proyectos"
|
||||
},
|
||||
"ERpq2P": {
|
||||
"message": "No results found for \"{debouncedQuery}\".",
|
||||
"placeholders": {
|
||||
@@ -3963,7 +4104,7 @@
|
||||
["src/components/DeleteLabelConfirmation.tsx", 26],
|
||||
["src/components/FeedbackModal.tsx", 41],
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/board/components/BoardDropdown.tsx", 63],
|
||||
["src/views/board/components/BoardDropdown.tsx", 65],
|
||||
["src/views/board/components/NewCardForm.tsx", 184],
|
||||
["src/views/board/components/NewListForm.tsx", 79],
|
||||
["src/views/board/components/NewTemplateForm.tsx", 61],
|
||||
@@ -3972,7 +4113,8 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 181],
|
||||
["src/views/board/index.tsx", 237],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 205],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 69],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 97],
|
||||
@@ -4178,7 +4320,7 @@
|
||||
"message": "Remove from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 92]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 121]],
|
||||
"translation": "Eliminar de favoritos"
|
||||
},
|
||||
"99VIgC": {
|
||||
@@ -4232,7 +4374,7 @@
|
||||
"message": "Removed from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 52]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"translation": "Eliminado de favoritos"
|
||||
},
|
||||
"YVT40D": {
|
||||
@@ -4426,14 +4568,17 @@
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 274]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 315],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 464]
|
||||
],
|
||||
"translation": "Seleccionar todo"
|
||||
},
|
||||
"rYUZIe": {
|
||||
"message": "Select source",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 157]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Seleccionar origen"
|
||||
},
|
||||
"ppaRWv": {
|
||||
@@ -4520,7 +4665,7 @@
|
||||
"message": "Settings | Integrations",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 69]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 138]],
|
||||
"translation": "Configuración | Integraciones"
|
||||
},
|
||||
"F/FPk/": {
|
||||
@@ -4570,8 +4715,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 34],
|
||||
["src/views/auth/signup/index.tsx", 59]
|
||||
["src/views/auth/signup/index.tsx", 36],
|
||||
["src/views/auth/signup/index.tsx", 61]
|
||||
],
|
||||
"translation": "Registrarse | kan.bn"
|
||||
},
|
||||
@@ -4579,14 +4724,14 @@
|
||||
"message": "Sign up disabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 44]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 46]],
|
||||
"translation": "Registro deshabilitado"
|
||||
},
|
||||
"s6iE/c": {
|
||||
"message": "Sign up is currently disabled. Please try again later.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 47]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 49]],
|
||||
"translation": "El registro está actualmente deshabilitado. Por favor, inténtalo de nuevo más tarde."
|
||||
},
|
||||
"6FDocz": {
|
||||
@@ -4809,6 +4954,20 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 34]],
|
||||
"translation": "¡Gracias por tus comentarios!"
|
||||
},
|
||||
"NcFrgC": {
|
||||
"message": "The board has been archived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 46]],
|
||||
"translation": "El tablero ha sido archivado."
|
||||
},
|
||||
"C6gv54": {
|
||||
"message": "The board has been unarchived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "El tablero ha sido desarchivado."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5001,6 +5160,13 @@
|
||||
"origin": [["src/views/home/components/Header.tsx", 114]],
|
||||
"translation": "Alternar menú"
|
||||
},
|
||||
"L5WQLg": {
|
||||
"message": "Token is required",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 19]],
|
||||
"translation": "Se requiere el token"
|
||||
},
|
||||
"eEQyz+": {
|
||||
"message": "Track all card changes with detailed activity history.",
|
||||
"placeholders": {},
|
||||
@@ -5014,7 +5180,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 218],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 73]
|
||||
["src/views/settings/IntegrationsSettings.tsx", 142]
|
||||
],
|
||||
"translation": "Trello"
|
||||
},
|
||||
@@ -5022,7 +5188,7 @@
|
||||
"message": "Trello disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 53]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 79]],
|
||||
"translation": "Trello desconectado"
|
||||
},
|
||||
"kxEs5t": {
|
||||
@@ -5196,7 +5362,7 @@
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 62]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 64]],
|
||||
"translation": "No se pudo actualizar el tablero"
|
||||
},
|
||||
"XpcjLO": {
|
||||
@@ -5292,6 +5458,13 @@
|
||||
"origin": [["src/views/members/index.tsx", 65]],
|
||||
"translation": "No se pudo actualizar el rol"
|
||||
},
|
||||
"It4/FS": {
|
||||
"message": "Unarchive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Desarchivar tablero"
|
||||
},
|
||||
"E8zYtd": {
|
||||
"message": "unassigned <0>{0}</0> from the card",
|
||||
"placeholders": {
|
||||
@@ -5671,7 +5844,7 @@
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 46],
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
["src/views/public/boards/index.tsx", 65]
|
||||
@@ -5883,9 +6056,9 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 474],
|
||||
["src/views/board/index.tsx", 532],
|
||||
["src/views/boards/components/BoardsList.tsx", 70],
|
||||
["src/views/boards/index.tsx", 46],
|
||||
["src/views/boards/index.tsx", 67]
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
],
|
||||
"translation": "No tienes permiso"
|
||||
},
|
||||
@@ -5951,7 +6124,7 @@
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 192]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 382]],
|
||||
"translation": "Tus tableros han sido importados."
|
||||
},
|
||||
"LqWW5F": {
|
||||
@@ -5968,6 +6141,27 @@
|
||||
"origin": [["src/views/card/components/AttachmentUpload.tsx", 46]],
|
||||
"translation": "Tu archivo se ha subido correctamente."
|
||||
},
|
||||
"HcT8J4": {
|
||||
"message": "Your GitHub account has been connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 100]],
|
||||
"translation": "Tu cuenta de GitHub ha sido conectada."
|
||||
},
|
||||
"AdxYds": {
|
||||
"message": "Your GitHub account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 123]],
|
||||
"translation": "Tu cuenta de GitHub ha sido desconectada."
|
||||
},
|
||||
"PELbXB": {
|
||||
"message": "Your GitHub account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 220]],
|
||||
"translation": "Tu cuenta de GitHub está conectada."
|
||||
},
|
||||
"Ozt2vv": {
|
||||
"message": "Your password has been changed.",
|
||||
"placeholders": {},
|
||||
@@ -5984,18 +6178,25 @@
|
||||
"origin": [["src/views/settings/components/Avatar.tsx", 190]],
|
||||
"translation": "Tu imagen de perfil ha sido actualizada."
|
||||
},
|
||||
"+jbXzb": {
|
||||
"message": "Your projects have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 230]],
|
||||
"translation": "Tus proyectos han sido importados."
|
||||
},
|
||||
"CJWDTP": {
|
||||
"message": "Your Trello account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 54]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"translation": "Tu cuenta de Trello ha sido desconectada."
|
||||
},
|
||||
"WRsbHO": {
|
||||
"message": "Your Trello account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 102]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 171]],
|
||||
"translation": "Tu cuenta de Trello está conectada."
|
||||
},
|
||||
"25fAUC": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -19,7 +19,7 @@
|
||||
"0": ["isTemplate ? \"Templates\" : \"Boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 40]],
|
||||
"origin": [["src/views/boards/index.tsx", 53]],
|
||||
"translation": "{0}"
|
||||
},
|
||||
"JArWcF": {
|
||||
@@ -33,8 +33,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/card/index.tsx", 309]
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/card/index.tsx", 308]
|
||||
],
|
||||
"translation": "{0} | {1}"
|
||||
},
|
||||
@@ -44,7 +44,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 56]],
|
||||
"translation": "{0} a été ajouté à vos favoris."
|
||||
},
|
||||
"bDI6VI": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 55]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 57]],
|
||||
"translation": "{0} a été retiré de vos favoris."
|
||||
},
|
||||
"CJukzS": {
|
||||
@@ -80,9 +80,18 @@
|
||||
"boardCount": ["boardCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 299]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 489]],
|
||||
"translation": "{boardCount, plural, one {Importer le tableau (1)} other {Importer les tableaux ({boardCount})}}"
|
||||
},
|
||||
"yndBF+": {
|
||||
"message": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}",
|
||||
"placeholders": {
|
||||
"projectCount": ["projectCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 341]],
|
||||
"translation": "{projectCount, plural, one {Importer le projet (1)} other {Importer les projets ({projectCount})}}"
|
||||
},
|
||||
"9lFfqv": {
|
||||
"message": "/month",
|
||||
"placeholders": {},
|
||||
@@ -185,12 +194,19 @@
|
||||
"origin": [["src/providers/keyboard-shortcuts.tsx", 56]],
|
||||
"translation": "Actions"
|
||||
},
|
||||
"F6pfE9": {
|
||||
"message": "Active",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 26]],
|
||||
"translation": "Actif"
|
||||
},
|
||||
"XJOV1Y": {
|
||||
"message": "Activity",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 447],
|
||||
["src/views/card/index.tsx", 446],
|
||||
["src/views/public/board/CardModal.tsx", 189]
|
||||
],
|
||||
"translation": "Activité"
|
||||
@@ -246,7 +262,7 @@
|
||||
"message": "Add description... (type '/' to open commands or '@' to mention)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/Editor.tsx", 471]],
|
||||
"origin": [["src/components/Editor.tsx", 482]],
|
||||
"translation": "Ajouter une description... (tapez « / » pour ouvrir les commandes ou « @ » pour mentionner)"
|
||||
},
|
||||
"abUZlY": {
|
||||
@@ -280,7 +296,7 @@
|
||||
"message": "Add to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 93]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 122]],
|
||||
"translation": "Ajouter aux favoris"
|
||||
},
|
||||
"bmXKoX": {
|
||||
@@ -368,7 +384,7 @@
|
||||
"message": "Added to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 51]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 53]],
|
||||
"translation": "Ajouté aux favoris"
|
||||
},
|
||||
"14Xi3Z": {
|
||||
@@ -482,14 +498,28 @@
|
||||
"message": "Already have an account? <0><1>Sign in</1></0>",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 88]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 90]],
|
||||
"translation": "Vous avez déjà un compte ? <0><1>Se connecter</1></0>"
|
||||
},
|
||||
"j1+HPc": {
|
||||
"message": "An error occurred while connecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 107]],
|
||||
"translation": "Une erreur s'est produite lors de la connexion de votre compte GitHub."
|
||||
},
|
||||
"Dz63YI": {
|
||||
"message": "An error occurred while disconnecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 130]],
|
||||
"translation": "Une erreur s'est produite lors de la déconnexion de votre compte GitHub."
|
||||
},
|
||||
"WmPhYW": {
|
||||
"message": "An error occurred while disconnecting your Trello account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 61]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 87]],
|
||||
"translation": "Une erreur s'est produite lors de la déconnexion de votre compte Trello."
|
||||
},
|
||||
"ZXSPJt": {
|
||||
@@ -574,6 +604,20 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 46]],
|
||||
"translation": "Approbation"
|
||||
},
|
||||
"aKJHG+": {
|
||||
"message": "Archive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Archiver le tableau"
|
||||
},
|
||||
"TdfEV7": {
|
||||
"message": "Archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 27]],
|
||||
"translation": "Archivé"
|
||||
},
|
||||
"lo8xBK": {
|
||||
"message": "Are you sure want to remove {entityLabel}?",
|
||||
"placeholders": {
|
||||
@@ -770,7 +814,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/card/index.tsx", 309],
|
||||
["src/views/card/index.tsx", 308],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
"translation": "Tableau"
|
||||
@@ -785,6 +829,13 @@
|
||||
],
|
||||
"translation": "Analytiques du tableau"
|
||||
},
|
||||
"i0ZMQl": {
|
||||
"message": "Board archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Tableau archivé"
|
||||
},
|
||||
"wewm3j": {
|
||||
"message": "Board name cannot exceed 100 characters",
|
||||
"placeholders": {},
|
||||
@@ -815,6 +866,13 @@
|
||||
],
|
||||
"translation": "Modèles de tableau"
|
||||
},
|
||||
"tbNcu4": {
|
||||
"message": "Board unarchived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Tableau désarchivé"
|
||||
},
|
||||
"Xid3K6": {
|
||||
"message": "Board URL can only contain letters, numbers, and hyphens",
|
||||
"placeholders": {},
|
||||
@@ -873,6 +931,13 @@
|
||||
],
|
||||
"translation": "Tableaux"
|
||||
},
|
||||
"0RE1AJ": {
|
||||
"message": "Boards you archive will appear here.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Les tableaux que vous archivez apparaîtront ici."
|
||||
},
|
||||
"ZDo4HN": {
|
||||
"message": "Brainstorming",
|
||||
"placeholders": {},
|
||||
@@ -1163,7 +1228,7 @@
|
||||
"message": "Card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 309]],
|
||||
"origin": [["src/views/card/index.tsx", 308]],
|
||||
"translation": "Carte"
|
||||
},
|
||||
"fEY2vP": {
|
||||
@@ -1171,8 +1236,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 355],
|
||||
["src/views/card/index.tsx", 392]
|
||||
["src/views/card/index.tsx", 354],
|
||||
["src/views/card/index.tsx", 391]
|
||||
],
|
||||
"translation": "Carte introuvable"
|
||||
},
|
||||
@@ -1237,7 +1302,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 43],
|
||||
["src/views/auth/signup/index.tsx", 69]
|
||||
["src/views/auth/signup/index.tsx", 71]
|
||||
],
|
||||
"translation": "Consultez votre boîte de réception"
|
||||
},
|
||||
@@ -1305,7 +1370,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 48],
|
||||
["src/views/auth/signup/index.tsx", 74]
|
||||
["src/views/auth/signup/index.tsx", 76]
|
||||
],
|
||||
"translation": "Cliquez sur le lien que nous avons envoyé à {magicLinkRecipient} pour vous connecter."
|
||||
},
|
||||
@@ -1314,7 +1379,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 346],
|
||||
["src/views/card/index.tsx", 345],
|
||||
["src/views/members/components/EditMemberPermissionsModal.tsx", 172],
|
||||
["src/views/settings/components/NewApiKeyModal.tsx", 136]
|
||||
],
|
||||
@@ -1431,14 +1496,25 @@
|
||||
],
|
||||
"translation": "Confirmez votre nouveau mot de passe"
|
||||
},
|
||||
"iSLIjg": {
|
||||
"message": "Connect",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Connecter"
|
||||
},
|
||||
"3jod3l": {
|
||||
"message": "Connect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 212]],
|
||||
"translation": "Connecter GitHub"
|
||||
},
|
||||
"nk7caK": {
|
||||
"message": "Connect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 157],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 93]
|
||||
],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 162]],
|
||||
"translation": "Connecter Trello"
|
||||
},
|
||||
"sDLCvT": {
|
||||
@@ -1448,11 +1524,18 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 122]],
|
||||
"translation": "Connectez vos outils préférés pour optimiser votre flux de travail."
|
||||
},
|
||||
"MCIXdZ": {
|
||||
"message": "Connect your GitHub account to import projects.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 191]],
|
||||
"translation": "Connectez votre compte GitHub pour importer des projets."
|
||||
},
|
||||
"5eZwRW": {
|
||||
"message": "Connect your Trello account to import boards.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 149]],
|
||||
"translation": "Connectez votre compte Trello pour importer des tableaux."
|
||||
},
|
||||
"jfC/xh": {
|
||||
@@ -1612,8 +1695,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/BoardsList.tsx", 79],
|
||||
["src/views/boards/index.tsx", 28]
|
||||
["src/views/boards/components/BoardsList.tsx", 80],
|
||||
["src/views/boards/index.tsx", 41]
|
||||
],
|
||||
"translation": "Créer un nouveau {0}"
|
||||
},
|
||||
@@ -1835,7 +1918,7 @@
|
||||
"message": "Delete board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Supprimer le tableau"
|
||||
},
|
||||
"nabda1": {
|
||||
@@ -1863,7 +1946,7 @@
|
||||
"message": "Delete template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Supprimer le modèle"
|
||||
},
|
||||
"kYu0eF": {
|
||||
@@ -1916,11 +1999,18 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 45]],
|
||||
"translation": "Design"
|
||||
},
|
||||
"Odv3J6": {
|
||||
"message": "Disconnect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 223]],
|
||||
"translation": "Déconnecter GitHub"
|
||||
},
|
||||
"YBBifR": {
|
||||
"message": "Disconnect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 108]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 177]],
|
||||
"translation": "Déconnecter Trello"
|
||||
},
|
||||
"1sRmLC": {
|
||||
@@ -2079,7 +2169,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/BoardDropdown.tsx", 84],
|
||||
["src/views/board/components/BoardDropdown.tsx", 102],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 116]
|
||||
],
|
||||
"translation": "Modifier l'URL du tableau"
|
||||
@@ -2265,6 +2355,13 @@
|
||||
],
|
||||
"translation": "Erreur lors du changement de mot de passe"
|
||||
},
|
||||
"yhLUU8": {
|
||||
"message": "Error connecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 106]],
|
||||
"translation": "Erreur de connexion à GitHub"
|
||||
},
|
||||
"cji2nM": {
|
||||
"message": "Error creating invite link",
|
||||
"placeholders": {},
|
||||
@@ -2304,11 +2401,18 @@
|
||||
],
|
||||
"translation": "Erreur lors de la suppression de l'espace de travail"
|
||||
},
|
||||
"gQ/02p": {
|
||||
"message": "Error disconnecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 129]],
|
||||
"translation": "Erreur de déconnexion de GitHub"
|
||||
},
|
||||
"lKAvEd": {
|
||||
"message": "Error disconnecting Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 60]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 86]],
|
||||
"translation": "Erreur lors de la déconnexion de Trello"
|
||||
},
|
||||
"rarRW/": {
|
||||
@@ -2622,7 +2726,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 69],
|
||||
["src/views/auth/signup/index.tsx", 71],
|
||||
["src/views/home/components/Cta.tsx", 61],
|
||||
["src/views/home/components/Header.tsx", 106],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 29],
|
||||
@@ -2647,7 +2751,7 @@
|
||||
"0": ["isTemplate ? \"template\" : \"board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 65]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Commencez en créant un nouveau {0}"
|
||||
},
|
||||
"zC8Whw": {
|
||||
@@ -2689,9 +2793,26 @@
|
||||
"message": "GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/home/components/Footer.tsx", 37]],
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 37],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 186]
|
||||
],
|
||||
"translation": "GitHub"
|
||||
},
|
||||
"PVT7q7": {
|
||||
"message": "GitHub connected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 99]],
|
||||
"translation": "GitHub connecté"
|
||||
},
|
||||
"/bBVaD": {
|
||||
"message": "GitHub disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 122]],
|
||||
"translation": "GitHub déconnecté"
|
||||
},
|
||||
"7eMo+U": {
|
||||
"message": "Go Home",
|
||||
"placeholders": {},
|
||||
@@ -2863,21 +2984,27 @@
|
||||
"message": "Import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 60]],
|
||||
"origin": [["src/views/boards/index.tsx", 73]],
|
||||
"translation": "Importer"
|
||||
},
|
||||
"2MPcep": {
|
||||
"message": "Import complete",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 191]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 229],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 381]
|
||||
],
|
||||
"translation": "Importation terminée"
|
||||
},
|
||||
"BEVzjL": {
|
||||
"message": "Import failed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 204]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 242],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 394]
|
||||
],
|
||||
"translation": "Échec de l'importation"
|
||||
},
|
||||
"rRM7r0": {
|
||||
@@ -3299,7 +3426,7 @@
|
||||
"message": "Make template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 73]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Créer un modèle"
|
||||
},
|
||||
"IDvohQ": {
|
||||
@@ -3432,7 +3559,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 82],
|
||||
["src/views/boards/index.tsx", 95],
|
||||
["src/views/home/components/Features.tsx", 73]
|
||||
],
|
||||
"translation": "Nouveau"
|
||||
@@ -3471,7 +3598,7 @@
|
||||
"message": "New import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 322]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 513]],
|
||||
"translation": "Nouvel import"
|
||||
},
|
||||
"n1GRql": {
|
||||
@@ -3550,9 +3677,16 @@
|
||||
"0": ["isTemplate ? \"templates\" : \"boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 62]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Aucun {0}"
|
||||
},
|
||||
"tlhgDC": {
|
||||
"message": "No archived boards",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Aucun tableau archivé"
|
||||
},
|
||||
"Eg99Sc": {
|
||||
"message": "No authentication methods are currently available",
|
||||
"placeholders": {},
|
||||
@@ -3564,7 +3698,7 @@
|
||||
"message": "No boards found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 242]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 432]],
|
||||
"translation": "Aucun tableau trouvé"
|
||||
},
|
||||
"OpNhRn": {
|
||||
@@ -3609,6 +3743,13 @@
|
||||
"origin": [["src/views/board/index.tsx", 527]],
|
||||
"translation": "Aucune liste n'a encore été créée"
|
||||
},
|
||||
"i30J2U": {
|
||||
"message": "No projects found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 283]],
|
||||
"translation": "Aucun projet trouvé"
|
||||
},
|
||||
"ERpq2P": {
|
||||
"message": "No results found for \"{debouncedQuery}\".",
|
||||
"placeholders": {
|
||||
@@ -3963,7 +4104,7 @@
|
||||
["src/components/DeleteLabelConfirmation.tsx", 26],
|
||||
["src/components/FeedbackModal.tsx", 41],
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/board/components/BoardDropdown.tsx", 63],
|
||||
["src/views/board/components/BoardDropdown.tsx", 65],
|
||||
["src/views/board/components/NewCardForm.tsx", 184],
|
||||
["src/views/board/components/NewListForm.tsx", 79],
|
||||
["src/views/board/components/NewTemplateForm.tsx", 61],
|
||||
@@ -3972,7 +4113,8 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 181],
|
||||
["src/views/board/index.tsx", 237],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 205],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 69],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 97],
|
||||
@@ -4178,7 +4320,7 @@
|
||||
"message": "Remove from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 92]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 121]],
|
||||
"translation": "Retirer des favoris"
|
||||
},
|
||||
"99VIgC": {
|
||||
@@ -4232,7 +4374,7 @@
|
||||
"message": "Removed from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 52]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"translation": "Retiré des favoris"
|
||||
},
|
||||
"YVT40D": {
|
||||
@@ -4426,14 +4568,17 @@
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 274]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 315],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 464]
|
||||
],
|
||||
"translation": "Tout sélectionner"
|
||||
},
|
||||
"rYUZIe": {
|
||||
"message": "Select source",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 157]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Sélectionner la source"
|
||||
},
|
||||
"ppaRWv": {
|
||||
@@ -4520,7 +4665,7 @@
|
||||
"message": "Settings | Integrations",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 69]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 138]],
|
||||
"translation": "Paramètres | Intégrations"
|
||||
},
|
||||
"F/FPk/": {
|
||||
@@ -4570,8 +4715,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 34],
|
||||
["src/views/auth/signup/index.tsx", 59]
|
||||
["src/views/auth/signup/index.tsx", 36],
|
||||
["src/views/auth/signup/index.tsx", 61]
|
||||
],
|
||||
"translation": "S'inscrire | kan.bn"
|
||||
},
|
||||
@@ -4579,14 +4724,14 @@
|
||||
"message": "Sign up disabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 44]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 46]],
|
||||
"translation": "Inscription désactivée"
|
||||
},
|
||||
"s6iE/c": {
|
||||
"message": "Sign up is currently disabled. Please try again later.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 47]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 49]],
|
||||
"translation": "L'inscription est actuellement désactivée. Veuillez réessayer plus tard."
|
||||
},
|
||||
"6FDocz": {
|
||||
@@ -4809,6 +4954,20 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 34]],
|
||||
"translation": "Merci pour votre retour !"
|
||||
},
|
||||
"NcFrgC": {
|
||||
"message": "The board has been archived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 46]],
|
||||
"translation": "Le tableau a été archivé."
|
||||
},
|
||||
"C6gv54": {
|
||||
"message": "The board has been unarchived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Le tableau a été désarchivé."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5001,6 +5160,13 @@
|
||||
"origin": [["src/views/home/components/Header.tsx", 114]],
|
||||
"translation": "Basculer le menu"
|
||||
},
|
||||
"L5WQLg": {
|
||||
"message": "Token is required",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 19]],
|
||||
"translation": "Le jeton est requis"
|
||||
},
|
||||
"eEQyz+": {
|
||||
"message": "Track all card changes with detailed activity history.",
|
||||
"placeholders": {},
|
||||
@@ -5014,7 +5180,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 218],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 73]
|
||||
["src/views/settings/IntegrationsSettings.tsx", 142]
|
||||
],
|
||||
"translation": "Trello"
|
||||
},
|
||||
@@ -5022,7 +5188,7 @@
|
||||
"message": "Trello disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 53]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 79]],
|
||||
"translation": "Trello déconnecté"
|
||||
},
|
||||
"kxEs5t": {
|
||||
@@ -5196,7 +5362,7 @@
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 62]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 64]],
|
||||
"translation": "Impossible de mettre à jour le tableau"
|
||||
},
|
||||
"XpcjLO": {
|
||||
@@ -5292,6 +5458,13 @@
|
||||
"origin": [["src/views/members/index.tsx", 65]],
|
||||
"translation": "Impossible de mettre à jour le rôle"
|
||||
},
|
||||
"It4/FS": {
|
||||
"message": "Unarchive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Désarchiver le tableau"
|
||||
},
|
||||
"E8zYtd": {
|
||||
"message": "unassigned <0>{0}</0> from the card",
|
||||
"placeholders": {
|
||||
@@ -5671,7 +5844,7 @@
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 46],
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
["src/views/public/boards/index.tsx", 65]
|
||||
@@ -5883,9 +6056,9 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 474],
|
||||
["src/views/board/index.tsx", 532],
|
||||
["src/views/boards/components/BoardsList.tsx", 70],
|
||||
["src/views/boards/index.tsx", 46],
|
||||
["src/views/boards/index.tsx", 67]
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
],
|
||||
"translation": "Vous n'avez pas la permission"
|
||||
},
|
||||
@@ -5951,7 +6124,7 @@
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 192]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 382]],
|
||||
"translation": "Vos tableaux ont été importés."
|
||||
},
|
||||
"LqWW5F": {
|
||||
@@ -5968,6 +6141,27 @@
|
||||
"origin": [["src/views/card/components/AttachmentUpload.tsx", 46]],
|
||||
"translation": "Votre fichier a été téléchargé avec succès."
|
||||
},
|
||||
"HcT8J4": {
|
||||
"message": "Your GitHub account has been connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 100]],
|
||||
"translation": "Votre compte GitHub a été connecté."
|
||||
},
|
||||
"AdxYds": {
|
||||
"message": "Your GitHub account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 123]],
|
||||
"translation": "Votre compte GitHub a été déconnecté."
|
||||
},
|
||||
"PELbXB": {
|
||||
"message": "Your GitHub account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 220]],
|
||||
"translation": "Votre compte GitHub est connecté."
|
||||
},
|
||||
"Ozt2vv": {
|
||||
"message": "Your password has been changed.",
|
||||
"placeholders": {},
|
||||
@@ -5984,18 +6178,25 @@
|
||||
"origin": [["src/views/settings/components/Avatar.tsx", 190]],
|
||||
"translation": "Votre image de profil a été mise à jour."
|
||||
},
|
||||
"+jbXzb": {
|
||||
"message": "Your projects have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 230]],
|
||||
"translation": "Vos projets ont été importés."
|
||||
},
|
||||
"CJWDTP": {
|
||||
"message": "Your Trello account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 54]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"translation": "Votre compte Trello a été déconnecté."
|
||||
},
|
||||
"WRsbHO": {
|
||||
"message": "Your Trello account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 102]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 171]],
|
||||
"translation": "Votre compte Trello est connecté."
|
||||
},
|
||||
"25fAUC": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,7 @@ export const locales = [
|
||||
"nl",
|
||||
"ru",
|
||||
"pl",
|
||||
"pt-BR"
|
||||
"ptbr"
|
||||
] as const;
|
||||
|
||||
export type Locale = (typeof locales)[number];
|
||||
@@ -23,5 +23,5 @@ export const localeNames: Record<Locale, string> = {
|
||||
nl: "Nederlands",
|
||||
ru: "Русский",
|
||||
pl: "Polski",
|
||||
"pt-BR": "Português",
|
||||
ptbr: "Português",
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"0": ["isTemplate ? \"Templates\" : \"Boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 40]],
|
||||
"origin": [["src/views/boards/index.tsx", 53]],
|
||||
"translation": "{0}"
|
||||
},
|
||||
"JArWcF": {
|
||||
@@ -33,8 +33,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/card/index.tsx", 309]
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/card/index.tsx", 308]
|
||||
],
|
||||
"translation": "{0} | {1}"
|
||||
},
|
||||
@@ -44,7 +44,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 56]],
|
||||
"translation": "{0} è stato aggiunto ai tuoi preferiti."
|
||||
},
|
||||
"bDI6VI": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 55]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 57]],
|
||||
"translation": "{0} è stato rimosso dai tuoi preferiti."
|
||||
},
|
||||
"CJukzS": {
|
||||
@@ -80,9 +80,18 @@
|
||||
"boardCount": ["boardCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 299]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 489]],
|
||||
"translation": "{boardCount, plural, one {Importa bacheca (1)} other {Importa bacheche ({boardCount})}}"
|
||||
},
|
||||
"yndBF+": {
|
||||
"message": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}",
|
||||
"placeholders": {
|
||||
"projectCount": ["projectCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 341]],
|
||||
"translation": "{projectCount, plural, one {Importa progetto (1)} other {Importa progetti ({projectCount})}}"
|
||||
},
|
||||
"9lFfqv": {
|
||||
"message": "/month",
|
||||
"placeholders": {},
|
||||
@@ -185,12 +194,19 @@
|
||||
"origin": [["src/providers/keyboard-shortcuts.tsx", 56]],
|
||||
"translation": "Azioni"
|
||||
},
|
||||
"F6pfE9": {
|
||||
"message": "Active",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 26]],
|
||||
"translation": "Attivo"
|
||||
},
|
||||
"XJOV1Y": {
|
||||
"message": "Activity",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 447],
|
||||
["src/views/card/index.tsx", 446],
|
||||
["src/views/public/board/CardModal.tsx", 189]
|
||||
],
|
||||
"translation": "Attività"
|
||||
@@ -246,7 +262,7 @@
|
||||
"message": "Add description... (type '/' to open commands or '@' to mention)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/Editor.tsx", 471]],
|
||||
"origin": [["src/components/Editor.tsx", 482]],
|
||||
"translation": "Aggiungi descrizione... (digita '/' per aprire i comandi o '@' per menzionare)"
|
||||
},
|
||||
"abUZlY": {
|
||||
@@ -280,7 +296,7 @@
|
||||
"message": "Add to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 93]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 122]],
|
||||
"translation": "Aggiungi ai preferiti"
|
||||
},
|
||||
"bmXKoX": {
|
||||
@@ -368,7 +384,7 @@
|
||||
"message": "Added to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 51]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 53]],
|
||||
"translation": "Aggiunto ai preferiti"
|
||||
},
|
||||
"14Xi3Z": {
|
||||
@@ -482,14 +498,28 @@
|
||||
"message": "Already have an account? <0><1>Sign in</1></0>",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 88]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 90]],
|
||||
"translation": "Hai già un account? <0><1>Accedi</1></0>"
|
||||
},
|
||||
"j1+HPc": {
|
||||
"message": "An error occurred while connecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 107]],
|
||||
"translation": "Si è verificato un errore durante la connessione del tuo account GitHub."
|
||||
},
|
||||
"Dz63YI": {
|
||||
"message": "An error occurred while disconnecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 130]],
|
||||
"translation": "Si è verificato un errore durante la disconnessione del tuo account GitHub."
|
||||
},
|
||||
"WmPhYW": {
|
||||
"message": "An error occurred while disconnecting your Trello account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 61]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 87]],
|
||||
"translation": "Si è verificato un errore durante la disconnessione del tuo account Trello."
|
||||
},
|
||||
"ZXSPJt": {
|
||||
@@ -574,6 +604,20 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 46]],
|
||||
"translation": "Approvazione"
|
||||
},
|
||||
"aKJHG+": {
|
||||
"message": "Archive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Archivia bacheca"
|
||||
},
|
||||
"TdfEV7": {
|
||||
"message": "Archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 27]],
|
||||
"translation": "Archiviato"
|
||||
},
|
||||
"lo8xBK": {
|
||||
"message": "Are you sure want to remove {entityLabel}?",
|
||||
"placeholders": {
|
||||
@@ -770,7 +814,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/card/index.tsx", 309],
|
||||
["src/views/card/index.tsx", 308],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
"translation": "Board"
|
||||
@@ -785,6 +829,13 @@
|
||||
],
|
||||
"translation": "Analisi della board"
|
||||
},
|
||||
"i0ZMQl": {
|
||||
"message": "Board archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Bacheca archiviata"
|
||||
},
|
||||
"wewm3j": {
|
||||
"message": "Board name cannot exceed 100 characters",
|
||||
"placeholders": {},
|
||||
@@ -815,6 +866,13 @@
|
||||
],
|
||||
"translation": "Template di board"
|
||||
},
|
||||
"tbNcu4": {
|
||||
"message": "Board unarchived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Bacheca ripristinata"
|
||||
},
|
||||
"Xid3K6": {
|
||||
"message": "Board URL can only contain letters, numbers, and hyphens",
|
||||
"placeholders": {},
|
||||
@@ -873,6 +931,13 @@
|
||||
],
|
||||
"translation": "Board"
|
||||
},
|
||||
"0RE1AJ": {
|
||||
"message": "Boards you archive will appear here.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Le bacheche che archivi appariranno qui."
|
||||
},
|
||||
"ZDo4HN": {
|
||||
"message": "Brainstorming",
|
||||
"placeholders": {},
|
||||
@@ -1163,7 +1228,7 @@
|
||||
"message": "Card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 309]],
|
||||
"origin": [["src/views/card/index.tsx", 308]],
|
||||
"translation": "Card"
|
||||
},
|
||||
"fEY2vP": {
|
||||
@@ -1171,8 +1236,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 355],
|
||||
["src/views/card/index.tsx", 392]
|
||||
["src/views/card/index.tsx", 354],
|
||||
["src/views/card/index.tsx", 391]
|
||||
],
|
||||
"translation": "Card non trovata"
|
||||
},
|
||||
@@ -1237,7 +1302,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 43],
|
||||
["src/views/auth/signup/index.tsx", 69]
|
||||
["src/views/auth/signup/index.tsx", 71]
|
||||
],
|
||||
"translation": "Controlla la tua casella di posta"
|
||||
},
|
||||
@@ -1305,7 +1370,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 48],
|
||||
["src/views/auth/signup/index.tsx", 74]
|
||||
["src/views/auth/signup/index.tsx", 76]
|
||||
],
|
||||
"translation": "Clicca sul link che abbiamo inviato a {magicLinkRecipient} per accedere."
|
||||
},
|
||||
@@ -1314,7 +1379,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 346],
|
||||
["src/views/card/index.tsx", 345],
|
||||
["src/views/members/components/EditMemberPermissionsModal.tsx", 172],
|
||||
["src/views/settings/components/NewApiKeyModal.tsx", 136]
|
||||
],
|
||||
@@ -1431,14 +1496,25 @@
|
||||
],
|
||||
"translation": "Conferma la tua nuova password"
|
||||
},
|
||||
"iSLIjg": {
|
||||
"message": "Connect",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Connetti"
|
||||
},
|
||||
"3jod3l": {
|
||||
"message": "Connect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 212]],
|
||||
"translation": "Connetti GitHub"
|
||||
},
|
||||
"nk7caK": {
|
||||
"message": "Connect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 157],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 93]
|
||||
],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 162]],
|
||||
"translation": "Connetti Trello"
|
||||
},
|
||||
"sDLCvT": {
|
||||
@@ -1448,11 +1524,18 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 122]],
|
||||
"translation": "Connetti i tuoi strumenti preferiti per semplificare il tuo flusso di lavoro."
|
||||
},
|
||||
"MCIXdZ": {
|
||||
"message": "Connect your GitHub account to import projects.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 191]],
|
||||
"translation": "Connetti il tuo account GitHub per importare progetti."
|
||||
},
|
||||
"5eZwRW": {
|
||||
"message": "Connect your Trello account to import boards.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 149]],
|
||||
"translation": "Connetti il tuo account Trello per importare le bacheche."
|
||||
},
|
||||
"jfC/xh": {
|
||||
@@ -1612,8 +1695,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/BoardsList.tsx", 79],
|
||||
["src/views/boards/index.tsx", 28]
|
||||
["src/views/boards/components/BoardsList.tsx", 80],
|
||||
["src/views/boards/index.tsx", 41]
|
||||
],
|
||||
"translation": "Crea nuovo {0}"
|
||||
},
|
||||
@@ -1835,7 +1918,7 @@
|
||||
"message": "Delete board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Elimina board"
|
||||
},
|
||||
"nabda1": {
|
||||
@@ -1863,7 +1946,7 @@
|
||||
"message": "Delete template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Elimina template"
|
||||
},
|
||||
"kYu0eF": {
|
||||
@@ -1916,11 +1999,18 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 45]],
|
||||
"translation": "Design"
|
||||
},
|
||||
"Odv3J6": {
|
||||
"message": "Disconnect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 223]],
|
||||
"translation": "Disconnetti GitHub"
|
||||
},
|
||||
"YBBifR": {
|
||||
"message": "Disconnect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 108]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 177]],
|
||||
"translation": "Disconnetti Trello"
|
||||
},
|
||||
"1sRmLC": {
|
||||
@@ -2079,7 +2169,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/BoardDropdown.tsx", 84],
|
||||
["src/views/board/components/BoardDropdown.tsx", 102],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 116]
|
||||
],
|
||||
"translation": "Modifica URL bacheca"
|
||||
@@ -2265,6 +2355,13 @@
|
||||
],
|
||||
"translation": "Errore durante la modifica della password"
|
||||
},
|
||||
"yhLUU8": {
|
||||
"message": "Error connecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 106]],
|
||||
"translation": "Errore nella connessione a GitHub"
|
||||
},
|
||||
"cji2nM": {
|
||||
"message": "Error creating invite link",
|
||||
"placeholders": {},
|
||||
@@ -2304,11 +2401,18 @@
|
||||
],
|
||||
"translation": "Errore durante l'eliminazione dello spazio di lavoro"
|
||||
},
|
||||
"gQ/02p": {
|
||||
"message": "Error disconnecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 129]],
|
||||
"translation": "Errore nella disconnessione da GitHub"
|
||||
},
|
||||
"lKAvEd": {
|
||||
"message": "Error disconnecting Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 60]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 86]],
|
||||
"translation": "Errore durante la disconnessione da Trello"
|
||||
},
|
||||
"rarRW/": {
|
||||
@@ -2622,7 +2726,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 69],
|
||||
["src/views/auth/signup/index.tsx", 71],
|
||||
["src/views/home/components/Cta.tsx", 61],
|
||||
["src/views/home/components/Header.tsx", 106],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 29],
|
||||
@@ -2647,7 +2751,7 @@
|
||||
"0": ["isTemplate ? \"template\" : \"board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 65]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Inizia creando un nuovo {0}"
|
||||
},
|
||||
"zC8Whw": {
|
||||
@@ -2689,9 +2793,26 @@
|
||||
"message": "GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/home/components/Footer.tsx", 37]],
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 37],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 186]
|
||||
],
|
||||
"translation": "GitHub"
|
||||
},
|
||||
"PVT7q7": {
|
||||
"message": "GitHub connected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 99]],
|
||||
"translation": "GitHub connesso"
|
||||
},
|
||||
"/bBVaD": {
|
||||
"message": "GitHub disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 122]],
|
||||
"translation": "GitHub disconnesso"
|
||||
},
|
||||
"7eMo+U": {
|
||||
"message": "Go Home",
|
||||
"placeholders": {},
|
||||
@@ -2863,21 +2984,27 @@
|
||||
"message": "Import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 60]],
|
||||
"origin": [["src/views/boards/index.tsx", 73]],
|
||||
"translation": "Importa"
|
||||
},
|
||||
"2MPcep": {
|
||||
"message": "Import complete",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 191]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 229],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 381]
|
||||
],
|
||||
"translation": "Importazione completata"
|
||||
},
|
||||
"BEVzjL": {
|
||||
"message": "Import failed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 204]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 242],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 394]
|
||||
],
|
||||
"translation": "Importazione fallita"
|
||||
},
|
||||
"rRM7r0": {
|
||||
@@ -3299,7 +3426,7 @@
|
||||
"message": "Make template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 73]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Crea template"
|
||||
},
|
||||
"IDvohQ": {
|
||||
@@ -3432,7 +3559,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 82],
|
||||
["src/views/boards/index.tsx", 95],
|
||||
["src/views/home/components/Features.tsx", 73]
|
||||
],
|
||||
"translation": "Nuovo"
|
||||
@@ -3471,7 +3598,7 @@
|
||||
"message": "New import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 322]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 513]],
|
||||
"translation": "Nuova importazione"
|
||||
},
|
||||
"n1GRql": {
|
||||
@@ -3550,9 +3677,16 @@
|
||||
"0": ["isTemplate ? \"templates\" : \"boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 62]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Nessun {0}"
|
||||
},
|
||||
"tlhgDC": {
|
||||
"message": "No archived boards",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Nessuna bacheca archiviata"
|
||||
},
|
||||
"Eg99Sc": {
|
||||
"message": "No authentication methods are currently available",
|
||||
"placeholders": {},
|
||||
@@ -3564,7 +3698,7 @@
|
||||
"message": "No boards found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 242]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 432]],
|
||||
"translation": "Nessuna board trovata"
|
||||
},
|
||||
"OpNhRn": {
|
||||
@@ -3609,6 +3743,13 @@
|
||||
"origin": [["src/views/board/index.tsx", 527]],
|
||||
"translation": "Nessuna lista è stata ancora creata"
|
||||
},
|
||||
"i30J2U": {
|
||||
"message": "No projects found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 283]],
|
||||
"translation": "Nessun progetto trovato"
|
||||
},
|
||||
"ERpq2P": {
|
||||
"message": "No results found for \"{debouncedQuery}\".",
|
||||
"placeholders": {
|
||||
@@ -3963,7 +4104,7 @@
|
||||
["src/components/DeleteLabelConfirmation.tsx", 26],
|
||||
["src/components/FeedbackModal.tsx", 41],
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/board/components/BoardDropdown.tsx", 63],
|
||||
["src/views/board/components/BoardDropdown.tsx", 65],
|
||||
["src/views/board/components/NewCardForm.tsx", 184],
|
||||
["src/views/board/components/NewListForm.tsx", 79],
|
||||
["src/views/board/components/NewTemplateForm.tsx", 61],
|
||||
@@ -3972,7 +4113,8 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 181],
|
||||
["src/views/board/index.tsx", 237],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 205],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 69],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 97],
|
||||
@@ -4178,7 +4320,7 @@
|
||||
"message": "Remove from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 92]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 121]],
|
||||
"translation": "Rimuovi dai preferiti"
|
||||
},
|
||||
"99VIgC": {
|
||||
@@ -4232,7 +4374,7 @@
|
||||
"message": "Removed from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 52]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"translation": "Rimosso dai preferiti"
|
||||
},
|
||||
"YVT40D": {
|
||||
@@ -4426,14 +4568,17 @@
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 274]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 315],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 464]
|
||||
],
|
||||
"translation": "Seleziona tutto"
|
||||
},
|
||||
"rYUZIe": {
|
||||
"message": "Select source",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 157]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Seleziona origine"
|
||||
},
|
||||
"ppaRWv": {
|
||||
@@ -4520,7 +4665,7 @@
|
||||
"message": "Settings | Integrations",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 69]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 138]],
|
||||
"translation": "Impostazioni | Integrazioni"
|
||||
},
|
||||
"F/FPk/": {
|
||||
@@ -4570,8 +4715,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 34],
|
||||
["src/views/auth/signup/index.tsx", 59]
|
||||
["src/views/auth/signup/index.tsx", 36],
|
||||
["src/views/auth/signup/index.tsx", 61]
|
||||
],
|
||||
"translation": "Registrati | kan.bn"
|
||||
},
|
||||
@@ -4579,14 +4724,14 @@
|
||||
"message": "Sign up disabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 44]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 46]],
|
||||
"translation": "Registrazione disabilitata"
|
||||
},
|
||||
"s6iE/c": {
|
||||
"message": "Sign up is currently disabled. Please try again later.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 47]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 49]],
|
||||
"translation": "La registrazione è attualmente disabilitata. Riprova più tardi."
|
||||
},
|
||||
"6FDocz": {
|
||||
@@ -4809,6 +4954,20 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 34]],
|
||||
"translation": "Grazie per il tuo feedback!"
|
||||
},
|
||||
"NcFrgC": {
|
||||
"message": "The board has been archived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 46]],
|
||||
"translation": "La bacheca è stata archiviata."
|
||||
},
|
||||
"C6gv54": {
|
||||
"message": "The board has been unarchived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "La bacheca è stata ripristinata."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5001,6 +5160,13 @@
|
||||
"origin": [["src/views/home/components/Header.tsx", 114]],
|
||||
"translation": "Attiva/disattiva menu"
|
||||
},
|
||||
"L5WQLg": {
|
||||
"message": "Token is required",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 19]],
|
||||
"translation": "Il token è obbligatorio"
|
||||
},
|
||||
"eEQyz+": {
|
||||
"message": "Track all card changes with detailed activity history.",
|
||||
"placeholders": {},
|
||||
@@ -5014,7 +5180,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 218],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 73]
|
||||
["src/views/settings/IntegrationsSettings.tsx", 142]
|
||||
],
|
||||
"translation": "Trello"
|
||||
},
|
||||
@@ -5022,7 +5188,7 @@
|
||||
"message": "Trello disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 53]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 79]],
|
||||
"translation": "Trello disconnesso"
|
||||
},
|
||||
"kxEs5t": {
|
||||
@@ -5196,7 +5362,7 @@
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 62]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 64]],
|
||||
"translation": "Impossibile aggiornare la board"
|
||||
},
|
||||
"XpcjLO": {
|
||||
@@ -5292,6 +5458,13 @@
|
||||
"origin": [["src/views/members/index.tsx", 65]],
|
||||
"translation": "Impossibile aggiornare il ruolo"
|
||||
},
|
||||
"It4/FS": {
|
||||
"message": "Unarchive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Ripristina bacheca"
|
||||
},
|
||||
"E8zYtd": {
|
||||
"message": "unassigned <0>{0}</0> from the card",
|
||||
"placeholders": {
|
||||
@@ -5671,7 +5844,7 @@
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 46],
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
["src/views/public/boards/index.tsx", 65]
|
||||
@@ -5883,9 +6056,9 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 474],
|
||||
["src/views/board/index.tsx", 532],
|
||||
["src/views/boards/components/BoardsList.tsx", 70],
|
||||
["src/views/boards/index.tsx", 46],
|
||||
["src/views/boards/index.tsx", 67]
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
],
|
||||
"translation": "Non hai i permessi necessari"
|
||||
},
|
||||
@@ -5951,7 +6124,7 @@
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 192]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 382]],
|
||||
"translation": "Le tue board sono state importate."
|
||||
},
|
||||
"LqWW5F": {
|
||||
@@ -5968,6 +6141,27 @@
|
||||
"origin": [["src/views/card/components/AttachmentUpload.tsx", 46]],
|
||||
"translation": "Il tuo file è stato caricato con successo."
|
||||
},
|
||||
"HcT8J4": {
|
||||
"message": "Your GitHub account has been connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 100]],
|
||||
"translation": "Il tuo account GitHub è stato connesso."
|
||||
},
|
||||
"AdxYds": {
|
||||
"message": "Your GitHub account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 123]],
|
||||
"translation": "Il tuo account GitHub è stato disconnesso."
|
||||
},
|
||||
"PELbXB": {
|
||||
"message": "Your GitHub account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 220]],
|
||||
"translation": "Il tuo account GitHub è connesso."
|
||||
},
|
||||
"Ozt2vv": {
|
||||
"message": "Your password has been changed.",
|
||||
"placeholders": {},
|
||||
@@ -5984,18 +6178,25 @@
|
||||
"origin": [["src/views/settings/components/Avatar.tsx", 190]],
|
||||
"translation": "La tua immagine del profilo è stata aggiornata."
|
||||
},
|
||||
"+jbXzb": {
|
||||
"message": "Your projects have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 230]],
|
||||
"translation": "I tuoi progetti sono stati importati."
|
||||
},
|
||||
"CJWDTP": {
|
||||
"message": "Your Trello account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 54]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"translation": "Il tuo account Trello è stato disconnesso."
|
||||
},
|
||||
"WRsbHO": {
|
||||
"message": "Your Trello account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 102]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 171]],
|
||||
"translation": "Il tuo account Trello è connesso."
|
||||
},
|
||||
"25fAUC": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -19,7 +19,7 @@
|
||||
"0": ["isTemplate ? \"Templates\" : \"Boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 40]],
|
||||
"origin": [["src/views/boards/index.tsx", 53]],
|
||||
"translation": "{0}"
|
||||
},
|
||||
"JArWcF": {
|
||||
@@ -33,8 +33,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/card/index.tsx", 309]
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/card/index.tsx", 308]
|
||||
],
|
||||
"translation": "{0} | {1}"
|
||||
},
|
||||
@@ -44,7 +44,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 56]],
|
||||
"translation": "{0} is toegevoegd aan je favorieten."
|
||||
},
|
||||
"bDI6VI": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 55]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 57]],
|
||||
"translation": "{0} is verwijderd uit je favorieten."
|
||||
},
|
||||
"CJukzS": {
|
||||
@@ -80,9 +80,18 @@
|
||||
"boardCount": ["boardCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 299]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 489]],
|
||||
"translation": "{boardCount, plural, one {Bord importeren (1)} other {Borden importeren ({boardCount})}}"
|
||||
},
|
||||
"yndBF+": {
|
||||
"message": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}",
|
||||
"placeholders": {
|
||||
"projectCount": ["projectCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 341]],
|
||||
"translation": "{projectCount, plural, one {Project importeren (1)} other {Projecten importeren ({projectCount})}}"
|
||||
},
|
||||
"9lFfqv": {
|
||||
"message": "/month",
|
||||
"placeholders": {},
|
||||
@@ -185,12 +194,19 @@
|
||||
"origin": [["src/providers/keyboard-shortcuts.tsx", 56]],
|
||||
"translation": "Acties"
|
||||
},
|
||||
"F6pfE9": {
|
||||
"message": "Active",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 26]],
|
||||
"translation": "Actief"
|
||||
},
|
||||
"XJOV1Y": {
|
||||
"message": "Activity",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 447],
|
||||
["src/views/card/index.tsx", 446],
|
||||
["src/views/public/board/CardModal.tsx", 189]
|
||||
],
|
||||
"translation": "Activiteit"
|
||||
@@ -246,7 +262,7 @@
|
||||
"message": "Add description... (type '/' to open commands or '@' to mention)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/Editor.tsx", 471]],
|
||||
"origin": [["src/components/Editor.tsx", 482]],
|
||||
"translation": "Voeg beschrijving toe... (typ '/' om commando's te openen of '@' om te vermelden)"
|
||||
},
|
||||
"abUZlY": {
|
||||
@@ -280,7 +296,7 @@
|
||||
"message": "Add to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 93]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 122]],
|
||||
"translation": "Toevoegen aan favorieten"
|
||||
},
|
||||
"bmXKoX": {
|
||||
@@ -368,7 +384,7 @@
|
||||
"message": "Added to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 51]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 53]],
|
||||
"translation": "Toegevoegd aan favorieten"
|
||||
},
|
||||
"14Xi3Z": {
|
||||
@@ -482,14 +498,28 @@
|
||||
"message": "Already have an account? <0><1>Sign in</1></0>",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 88]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 90]],
|
||||
"translation": "Heb je al een account? <0><1>Inloggen</1></0>"
|
||||
},
|
||||
"j1+HPc": {
|
||||
"message": "An error occurred while connecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 107]],
|
||||
"translation": "Er is een fout opgetreden bij het verbinden van je GitHub-account."
|
||||
},
|
||||
"Dz63YI": {
|
||||
"message": "An error occurred while disconnecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 130]],
|
||||
"translation": "Er is een fout opgetreden bij het loskoppelen van je GitHub-account."
|
||||
},
|
||||
"WmPhYW": {
|
||||
"message": "An error occurred while disconnecting your Trello account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 61]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 87]],
|
||||
"translation": "Er is een fout opgetreden bij het loskoppelen van je Trello-account."
|
||||
},
|
||||
"ZXSPJt": {
|
||||
@@ -574,6 +604,20 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 46]],
|
||||
"translation": "Goedkeuring"
|
||||
},
|
||||
"aKJHG+": {
|
||||
"message": "Archive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Board archiveren"
|
||||
},
|
||||
"TdfEV7": {
|
||||
"message": "Archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 27]],
|
||||
"translation": "Gearchiveerd"
|
||||
},
|
||||
"lo8xBK": {
|
||||
"message": "Are you sure want to remove {entityLabel}?",
|
||||
"placeholders": {
|
||||
@@ -770,7 +814,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/card/index.tsx", 309],
|
||||
["src/views/card/index.tsx", 308],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
"translation": "Bord"
|
||||
@@ -785,6 +829,13 @@
|
||||
],
|
||||
"translation": "Bordanalyse"
|
||||
},
|
||||
"i0ZMQl": {
|
||||
"message": "Board archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Board gearchiveerd"
|
||||
},
|
||||
"wewm3j": {
|
||||
"message": "Board name cannot exceed 100 characters",
|
||||
"placeholders": {},
|
||||
@@ -815,6 +866,13 @@
|
||||
],
|
||||
"translation": "Bordsjablonen"
|
||||
},
|
||||
"tbNcu4": {
|
||||
"message": "Board unarchived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Board gedearchiveerd"
|
||||
},
|
||||
"Xid3K6": {
|
||||
"message": "Board URL can only contain letters, numbers, and hyphens",
|
||||
"placeholders": {},
|
||||
@@ -873,6 +931,13 @@
|
||||
],
|
||||
"translation": "Boards"
|
||||
},
|
||||
"0RE1AJ": {
|
||||
"message": "Boards you archive will appear here.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Boards die je archiveert verschijnen hier."
|
||||
},
|
||||
"ZDo4HN": {
|
||||
"message": "Brainstorming",
|
||||
"placeholders": {},
|
||||
@@ -1163,7 +1228,7 @@
|
||||
"message": "Card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 309]],
|
||||
"origin": [["src/views/card/index.tsx", 308]],
|
||||
"translation": "Kaart"
|
||||
},
|
||||
"fEY2vP": {
|
||||
@@ -1171,8 +1236,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 355],
|
||||
["src/views/card/index.tsx", 392]
|
||||
["src/views/card/index.tsx", 354],
|
||||
["src/views/card/index.tsx", 391]
|
||||
],
|
||||
"translation": "Kaart niet gevonden"
|
||||
},
|
||||
@@ -1237,7 +1302,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 43],
|
||||
["src/views/auth/signup/index.tsx", 69]
|
||||
["src/views/auth/signup/index.tsx", 71]
|
||||
],
|
||||
"translation": "Controleer je inbox"
|
||||
},
|
||||
@@ -1305,7 +1370,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 48],
|
||||
["src/views/auth/signup/index.tsx", 74]
|
||||
["src/views/auth/signup/index.tsx", 76]
|
||||
],
|
||||
"translation": "Klik op de link die we naar {magicLinkRecipient} hebben gestuurd om in te loggen."
|
||||
},
|
||||
@@ -1314,7 +1379,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 346],
|
||||
["src/views/card/index.tsx", 345],
|
||||
["src/views/members/components/EditMemberPermissionsModal.tsx", 172],
|
||||
["src/views/settings/components/NewApiKeyModal.tsx", 136]
|
||||
],
|
||||
@@ -1431,14 +1496,25 @@
|
||||
],
|
||||
"translation": "Bevestig je nieuwe wachtwoord"
|
||||
},
|
||||
"iSLIjg": {
|
||||
"message": "Connect",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Verbinden"
|
||||
},
|
||||
"3jod3l": {
|
||||
"message": "Connect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 212]],
|
||||
"translation": "GitHub verbinden"
|
||||
},
|
||||
"nk7caK": {
|
||||
"message": "Connect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 157],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 93]
|
||||
],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 162]],
|
||||
"translation": "Verbind Trello"
|
||||
},
|
||||
"sDLCvT": {
|
||||
@@ -1448,11 +1524,18 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 122]],
|
||||
"translation": "Verbind je favoriete tools om je workflow te stroomlijnen."
|
||||
},
|
||||
"MCIXdZ": {
|
||||
"message": "Connect your GitHub account to import projects.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 191]],
|
||||
"translation": "Verbind je GitHub-account om projecten te importeren."
|
||||
},
|
||||
"5eZwRW": {
|
||||
"message": "Connect your Trello account to import boards.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 149]],
|
||||
"translation": "Verbind je Trello-account om boards te importeren."
|
||||
},
|
||||
"jfC/xh": {
|
||||
@@ -1612,8 +1695,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/BoardsList.tsx", 79],
|
||||
["src/views/boards/index.tsx", 28]
|
||||
["src/views/boards/components/BoardsList.tsx", 80],
|
||||
["src/views/boards/index.tsx", 41]
|
||||
],
|
||||
"translation": "Maak nieuwe {0}"
|
||||
},
|
||||
@@ -1835,7 +1918,7 @@
|
||||
"message": "Delete board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Bord verwijderen"
|
||||
},
|
||||
"nabda1": {
|
||||
@@ -1863,7 +1946,7 @@
|
||||
"message": "Delete template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Sjabloon verwijderen"
|
||||
},
|
||||
"kYu0eF": {
|
||||
@@ -1916,11 +1999,18 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 45]],
|
||||
"translation": "Ontwerp"
|
||||
},
|
||||
"Odv3J6": {
|
||||
"message": "Disconnect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 223]],
|
||||
"translation": "GitHub loskoppelen"
|
||||
},
|
||||
"YBBifR": {
|
||||
"message": "Disconnect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 108]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 177]],
|
||||
"translation": "Trello loskoppelen"
|
||||
},
|
||||
"1sRmLC": {
|
||||
@@ -2079,7 +2169,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/BoardDropdown.tsx", 84],
|
||||
["src/views/board/components/BoardDropdown.tsx", 102],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 116]
|
||||
],
|
||||
"translation": "Bord-URL bewerken"
|
||||
@@ -2265,6 +2355,13 @@
|
||||
],
|
||||
"translation": "Fout bij wijzigen wachtwoord"
|
||||
},
|
||||
"yhLUU8": {
|
||||
"message": "Error connecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 106]],
|
||||
"translation": "Fout bij verbinden met GitHub"
|
||||
},
|
||||
"cji2nM": {
|
||||
"message": "Error creating invite link",
|
||||
"placeholders": {},
|
||||
@@ -2304,11 +2401,18 @@
|
||||
],
|
||||
"translation": "Fout bij verwijderen werkruimte"
|
||||
},
|
||||
"gQ/02p": {
|
||||
"message": "Error disconnecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 129]],
|
||||
"translation": "Fout bij loskoppelen van GitHub"
|
||||
},
|
||||
"lKAvEd": {
|
||||
"message": "Error disconnecting Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 60]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 86]],
|
||||
"translation": "Fout bij loskoppelen Trello"
|
||||
},
|
||||
"rarRW/": {
|
||||
@@ -2622,7 +2726,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 69],
|
||||
["src/views/auth/signup/index.tsx", 71],
|
||||
["src/views/home/components/Cta.tsx", 61],
|
||||
["src/views/home/components/Header.tsx", 106],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 29],
|
||||
@@ -2647,7 +2751,7 @@
|
||||
"0": ["isTemplate ? \"template\" : \"board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 65]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Ga aan de slag door een nieuwe {0} te maken"
|
||||
},
|
||||
"zC8Whw": {
|
||||
@@ -2689,9 +2793,26 @@
|
||||
"message": "GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/home/components/Footer.tsx", 37]],
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 37],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 186]
|
||||
],
|
||||
"translation": "GitHub"
|
||||
},
|
||||
"PVT7q7": {
|
||||
"message": "GitHub connected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 99]],
|
||||
"translation": "GitHub verbonden"
|
||||
},
|
||||
"/bBVaD": {
|
||||
"message": "GitHub disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 122]],
|
||||
"translation": "GitHub losgekoppeld"
|
||||
},
|
||||
"7eMo+U": {
|
||||
"message": "Go Home",
|
||||
"placeholders": {},
|
||||
@@ -2863,21 +2984,27 @@
|
||||
"message": "Import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 60]],
|
||||
"origin": [["src/views/boards/index.tsx", 73]],
|
||||
"translation": "Importeren"
|
||||
},
|
||||
"2MPcep": {
|
||||
"message": "Import complete",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 191]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 229],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 381]
|
||||
],
|
||||
"translation": "Import voltooid"
|
||||
},
|
||||
"BEVzjL": {
|
||||
"message": "Import failed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 204]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 242],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 394]
|
||||
],
|
||||
"translation": "Import mislukt"
|
||||
},
|
||||
"rRM7r0": {
|
||||
@@ -3299,7 +3426,7 @@
|
||||
"message": "Make template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 73]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Sjabloon maken"
|
||||
},
|
||||
"IDvohQ": {
|
||||
@@ -3432,7 +3559,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 82],
|
||||
["src/views/boards/index.tsx", 95],
|
||||
["src/views/home/components/Features.tsx", 73]
|
||||
],
|
||||
"translation": "Nieuw"
|
||||
@@ -3471,7 +3598,7 @@
|
||||
"message": "New import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 322]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 513]],
|
||||
"translation": "Nieuwe import"
|
||||
},
|
||||
"n1GRql": {
|
||||
@@ -3550,9 +3677,16 @@
|
||||
"0": ["isTemplate ? \"templates\" : \"boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 62]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Geen {0}"
|
||||
},
|
||||
"tlhgDC": {
|
||||
"message": "No archived boards",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Geen gearchiveerde boards"
|
||||
},
|
||||
"Eg99Sc": {
|
||||
"message": "No authentication methods are currently available",
|
||||
"placeholders": {},
|
||||
@@ -3564,7 +3698,7 @@
|
||||
"message": "No boards found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 242]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 432]],
|
||||
"translation": "Geen borden gevonden"
|
||||
},
|
||||
"OpNhRn": {
|
||||
@@ -3609,6 +3743,13 @@
|
||||
"origin": [["src/views/board/index.tsx", 527]],
|
||||
"translation": "Er zijn nog geen lijsten aangemaakt"
|
||||
},
|
||||
"i30J2U": {
|
||||
"message": "No projects found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 283]],
|
||||
"translation": "Geen projecten gevonden"
|
||||
},
|
||||
"ERpq2P": {
|
||||
"message": "No results found for \"{debouncedQuery}\".",
|
||||
"placeholders": {
|
||||
@@ -3963,7 +4104,7 @@
|
||||
["src/components/DeleteLabelConfirmation.tsx", 26],
|
||||
["src/components/FeedbackModal.tsx", 41],
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/board/components/BoardDropdown.tsx", 63],
|
||||
["src/views/board/components/BoardDropdown.tsx", 65],
|
||||
["src/views/board/components/NewCardForm.tsx", 184],
|
||||
["src/views/board/components/NewListForm.tsx", 79],
|
||||
["src/views/board/components/NewTemplateForm.tsx", 61],
|
||||
@@ -3972,7 +4113,8 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 181],
|
||||
["src/views/board/index.tsx", 237],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 205],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 69],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 97],
|
||||
@@ -4178,7 +4320,7 @@
|
||||
"message": "Remove from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 92]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 121]],
|
||||
"translation": "Verwijderen uit favorieten"
|
||||
},
|
||||
"99VIgC": {
|
||||
@@ -4232,7 +4374,7 @@
|
||||
"message": "Removed from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 52]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"translation": "Verwijderd uit favorieten"
|
||||
},
|
||||
"YVT40D": {
|
||||
@@ -4426,14 +4568,17 @@
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 274]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 315],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 464]
|
||||
],
|
||||
"translation": "Alles selecteren"
|
||||
},
|
||||
"rYUZIe": {
|
||||
"message": "Select source",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 157]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Selecteer bron"
|
||||
},
|
||||
"ppaRWv": {
|
||||
@@ -4520,7 +4665,7 @@
|
||||
"message": "Settings | Integrations",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 69]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 138]],
|
||||
"translation": "Instellingen | Integraties"
|
||||
},
|
||||
"F/FPk/": {
|
||||
@@ -4570,8 +4715,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 34],
|
||||
["src/views/auth/signup/index.tsx", 59]
|
||||
["src/views/auth/signup/index.tsx", 36],
|
||||
["src/views/auth/signup/index.tsx", 61]
|
||||
],
|
||||
"translation": "Registreren | kan.bn"
|
||||
},
|
||||
@@ -4579,14 +4724,14 @@
|
||||
"message": "Sign up disabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 44]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 46]],
|
||||
"translation": "Registratie uitgeschakeld"
|
||||
},
|
||||
"s6iE/c": {
|
||||
"message": "Sign up is currently disabled. Please try again later.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 47]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 49]],
|
||||
"translation": "Registratie is momenteel uitgeschakeld. Probeer het later opnieuw."
|
||||
},
|
||||
"6FDocz": {
|
||||
@@ -4809,6 +4954,20 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 34]],
|
||||
"translation": "Bedankt voor je feedback!"
|
||||
},
|
||||
"NcFrgC": {
|
||||
"message": "The board has been archived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 46]],
|
||||
"translation": "Het board is gearchiveerd."
|
||||
},
|
||||
"C6gv54": {
|
||||
"message": "The board has been unarchived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Het board is gedearchiveerd."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5001,6 +5160,13 @@
|
||||
"origin": [["src/views/home/components/Header.tsx", 114]],
|
||||
"translation": "Menu in-/uitschakelen"
|
||||
},
|
||||
"L5WQLg": {
|
||||
"message": "Token is required",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 19]],
|
||||
"translation": "Token is vereist"
|
||||
},
|
||||
"eEQyz+": {
|
||||
"message": "Track all card changes with detailed activity history.",
|
||||
"placeholders": {},
|
||||
@@ -5014,7 +5180,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 218],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 73]
|
||||
["src/views/settings/IntegrationsSettings.tsx", 142]
|
||||
],
|
||||
"translation": "Trello"
|
||||
},
|
||||
@@ -5022,7 +5188,7 @@
|
||||
"message": "Trello disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 53]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 79]],
|
||||
"translation": "Trello losgekoppeld"
|
||||
},
|
||||
"kxEs5t": {
|
||||
@@ -5196,7 +5362,7 @@
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 62]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 64]],
|
||||
"translation": "Kan bord niet bijwerken"
|
||||
},
|
||||
"XpcjLO": {
|
||||
@@ -5292,6 +5458,13 @@
|
||||
"origin": [["src/views/members/index.tsx", 65]],
|
||||
"translation": "Kan rol niet bijwerken"
|
||||
},
|
||||
"It4/FS": {
|
||||
"message": "Unarchive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Board dearchiveren"
|
||||
},
|
||||
"E8zYtd": {
|
||||
"message": "unassigned <0>{0}</0> from the card",
|
||||
"placeholders": {
|
||||
@@ -5671,7 +5844,7 @@
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 46],
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
["src/views/public/boards/index.tsx", 65]
|
||||
@@ -5883,9 +6056,9 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 474],
|
||||
["src/views/board/index.tsx", 532],
|
||||
["src/views/boards/components/BoardsList.tsx", 70],
|
||||
["src/views/boards/index.tsx", 46],
|
||||
["src/views/boards/index.tsx", 67]
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
],
|
||||
"translation": "Je hebt geen toestemming"
|
||||
},
|
||||
@@ -5951,7 +6124,7 @@
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 192]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 382]],
|
||||
"translation": "Je borden zijn geïmporteerd."
|
||||
},
|
||||
"LqWW5F": {
|
||||
@@ -5968,6 +6141,27 @@
|
||||
"origin": [["src/views/card/components/AttachmentUpload.tsx", 46]],
|
||||
"translation": "Je bestand is succesvol geüpload."
|
||||
},
|
||||
"HcT8J4": {
|
||||
"message": "Your GitHub account has been connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 100]],
|
||||
"translation": "Je GitHub-account is gekoppeld."
|
||||
},
|
||||
"AdxYds": {
|
||||
"message": "Your GitHub account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 123]],
|
||||
"translation": "Je GitHub-account is ontkoppeld."
|
||||
},
|
||||
"PELbXB": {
|
||||
"message": "Your GitHub account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 220]],
|
||||
"translation": "Je GitHub-account is gekoppeld."
|
||||
},
|
||||
"Ozt2vv": {
|
||||
"message": "Your password has been changed.",
|
||||
"placeholders": {},
|
||||
@@ -5984,18 +6178,25 @@
|
||||
"origin": [["src/views/settings/components/Avatar.tsx", 190]],
|
||||
"translation": "Je profielafbeelding is bijgewerkt."
|
||||
},
|
||||
"+jbXzb": {
|
||||
"message": "Your projects have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 230]],
|
||||
"translation": "Je projecten zijn geïmporteerd."
|
||||
},
|
||||
"CJWDTP": {
|
||||
"message": "Your Trello account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 54]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"translation": "Je Trello-account is losgekoppeld."
|
||||
},
|
||||
"WRsbHO": {
|
||||
"message": "Your Trello account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 102]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 171]],
|
||||
"translation": "Je Trello-account is gekoppeld."
|
||||
},
|
||||
"25fAUC": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -19,7 +19,7 @@
|
||||
"0": ["isTemplate ? \"Templates\" : \"Boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 40]],
|
||||
"origin": [["src/views/boards/index.tsx", 53]],
|
||||
"translation": "{0}"
|
||||
},
|
||||
"JArWcF": {
|
||||
@@ -33,8 +33,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/card/index.tsx", 309]
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/card/index.tsx", 308]
|
||||
],
|
||||
"translation": "{0} | {1}"
|
||||
},
|
||||
@@ -44,7 +44,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 56]],
|
||||
"translation": "{0} został dodany do ulubionych."
|
||||
},
|
||||
"bDI6VI": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 55]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 57]],
|
||||
"translation": "{0} został usunięty z ulubionych."
|
||||
},
|
||||
"CJukzS": {
|
||||
@@ -80,9 +80,18 @@
|
||||
"boardCount": ["boardCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 299]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 489]],
|
||||
"translation": "{boardCount, plural, one {Importuj tablicę (1)} few {Importuj tablice ({boardCount})} many {Importuj tablic ({boardCount})} other {Importuj tablice ({boardCount})}}"
|
||||
},
|
||||
"yndBF+": {
|
||||
"message": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}",
|
||||
"placeholders": {
|
||||
"projectCount": ["projectCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 341]],
|
||||
"translation": "{projectCount, plural, one {Importuj projekt (1)} few {Importuj projekty ({projectCount})} many {Importuj projektów ({projectCount})} other {Importuj projekty ({projectCount})}}"
|
||||
},
|
||||
"9lFfqv": {
|
||||
"message": "/month",
|
||||
"placeholders": {},
|
||||
@@ -185,12 +194,19 @@
|
||||
"origin": [["src/providers/keyboard-shortcuts.tsx", 56]],
|
||||
"translation": "Akcje"
|
||||
},
|
||||
"F6pfE9": {
|
||||
"message": "Active",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 26]],
|
||||
"translation": "Aktywna"
|
||||
},
|
||||
"XJOV1Y": {
|
||||
"message": "Activity",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 447],
|
||||
["src/views/card/index.tsx", 446],
|
||||
["src/views/public/board/CardModal.tsx", 189]
|
||||
],
|
||||
"translation": "Aktywność"
|
||||
@@ -246,7 +262,7 @@
|
||||
"message": "Add description... (type '/' to open commands or '@' to mention)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/Editor.tsx", 471]],
|
||||
"origin": [["src/components/Editor.tsx", 482]],
|
||||
"translation": "Dodaj opis... (wpisz '/' aby otworzyć polecenia lub '@', aby wspomnieć)"
|
||||
},
|
||||
"abUZlY": {
|
||||
@@ -280,7 +296,7 @@
|
||||
"message": "Add to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 93]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 122]],
|
||||
"translation": "Dodaj do ulubionych"
|
||||
},
|
||||
"bmXKoX": {
|
||||
@@ -368,7 +384,7 @@
|
||||
"message": "Added to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 51]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 53]],
|
||||
"translation": "Dodano do ulubionych"
|
||||
},
|
||||
"14Xi3Z": {
|
||||
@@ -482,14 +498,28 @@
|
||||
"message": "Already have an account? <0><1>Sign in</1></0>",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 88]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 90]],
|
||||
"translation": "Masz już konto? <0><1>Zaloguj się</1></0>"
|
||||
},
|
||||
"j1+HPc": {
|
||||
"message": "An error occurred while connecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 107]],
|
||||
"translation": "Wystąpił błąd podczas łączenia konta GitHub."
|
||||
},
|
||||
"Dz63YI": {
|
||||
"message": "An error occurred while disconnecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 130]],
|
||||
"translation": "Wystąpił błąd podczas odłączania konta GitHub."
|
||||
},
|
||||
"WmPhYW": {
|
||||
"message": "An error occurred while disconnecting your Trello account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 61]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 87]],
|
||||
"translation": "Wystąpił błąd podczas odłączania konta Trello."
|
||||
},
|
||||
"ZXSPJt": {
|
||||
@@ -574,6 +604,20 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 46]],
|
||||
"translation": "Zatwierdzenie"
|
||||
},
|
||||
"aKJHG+": {
|
||||
"message": "Archive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Zarchiwizuj tablicę"
|
||||
},
|
||||
"TdfEV7": {
|
||||
"message": "Archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 27]],
|
||||
"translation": "Zarchiwizowana"
|
||||
},
|
||||
"lo8xBK": {
|
||||
"message": "Are you sure want to remove {entityLabel}?",
|
||||
"placeholders": {
|
||||
@@ -770,7 +814,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/card/index.tsx", 309],
|
||||
["src/views/card/index.tsx", 308],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
"translation": "Tablica"
|
||||
@@ -785,6 +829,13 @@
|
||||
],
|
||||
"translation": "Analiza tablicy"
|
||||
},
|
||||
"i0ZMQl": {
|
||||
"message": "Board archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Tablica zarchiwizowana"
|
||||
},
|
||||
"wewm3j": {
|
||||
"message": "Board name cannot exceed 100 characters",
|
||||
"placeholders": {},
|
||||
@@ -815,6 +866,13 @@
|
||||
],
|
||||
"translation": "Szablony tablic"
|
||||
},
|
||||
"tbNcu4": {
|
||||
"message": "Board unarchived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Tablica przywrócona z archiwum"
|
||||
},
|
||||
"Xid3K6": {
|
||||
"message": "Board URL can only contain letters, numbers, and hyphens",
|
||||
"placeholders": {},
|
||||
@@ -873,6 +931,13 @@
|
||||
],
|
||||
"translation": "Tablice"
|
||||
},
|
||||
"0RE1AJ": {
|
||||
"message": "Boards you archive will appear here.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Zarchiwizowane tablice pojawią się tutaj."
|
||||
},
|
||||
"ZDo4HN": {
|
||||
"message": "Brainstorming",
|
||||
"placeholders": {},
|
||||
@@ -1163,7 +1228,7 @@
|
||||
"message": "Card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 309]],
|
||||
"origin": [["src/views/card/index.tsx", 308]],
|
||||
"translation": "Karta"
|
||||
},
|
||||
"fEY2vP": {
|
||||
@@ -1171,8 +1236,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 355],
|
||||
["src/views/card/index.tsx", 392]
|
||||
["src/views/card/index.tsx", 354],
|
||||
["src/views/card/index.tsx", 391]
|
||||
],
|
||||
"translation": "Nie znaleziono karty"
|
||||
},
|
||||
@@ -1237,7 +1302,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 43],
|
||||
["src/views/auth/signup/index.tsx", 69]
|
||||
["src/views/auth/signup/index.tsx", 71]
|
||||
],
|
||||
"translation": "Sprawdź swoją skrzynkę odbiorczą"
|
||||
},
|
||||
@@ -1305,7 +1370,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 48],
|
||||
["src/views/auth/signup/index.tsx", 74]
|
||||
["src/views/auth/signup/index.tsx", 76]
|
||||
],
|
||||
"translation": "Kliknij w link, który wysłaliśmy do {magicLinkRecipient}, aby się zalogować."
|
||||
},
|
||||
@@ -1314,7 +1379,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 346],
|
||||
["src/views/card/index.tsx", 345],
|
||||
["src/views/members/components/EditMemberPermissionsModal.tsx", 172],
|
||||
["src/views/settings/components/NewApiKeyModal.tsx", 136]
|
||||
],
|
||||
@@ -1431,14 +1496,25 @@
|
||||
],
|
||||
"translation": "Potwierdź nowe hasło"
|
||||
},
|
||||
"iSLIjg": {
|
||||
"message": "Connect",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Połącz"
|
||||
},
|
||||
"3jod3l": {
|
||||
"message": "Connect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 212]],
|
||||
"translation": "Połącz z GitHub"
|
||||
},
|
||||
"nk7caK": {
|
||||
"message": "Connect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 157],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 93]
|
||||
],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 162]],
|
||||
"translation": "Połącz Trello"
|
||||
},
|
||||
"sDLCvT": {
|
||||
@@ -1448,11 +1524,18 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 122]],
|
||||
"translation": "Połącz swoje ulubione narzędzia, aby usprawnić pracę."
|
||||
},
|
||||
"MCIXdZ": {
|
||||
"message": "Connect your GitHub account to import projects.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 191]],
|
||||
"translation": "Połącz swoje konto GitHub, aby zaimportować projekty."
|
||||
},
|
||||
"5eZwRW": {
|
||||
"message": "Connect your Trello account to import boards.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 149]],
|
||||
"translation": "Połącz swoje konto Trello, aby zaimportować tablice."
|
||||
},
|
||||
"jfC/xh": {
|
||||
@@ -1612,8 +1695,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/BoardsList.tsx", 79],
|
||||
["src/views/boards/index.tsx", 28]
|
||||
["src/views/boards/components/BoardsList.tsx", 80],
|
||||
["src/views/boards/index.tsx", 41]
|
||||
],
|
||||
"translation": "Utwórz nową {0}"
|
||||
},
|
||||
@@ -1835,7 +1918,7 @@
|
||||
"message": "Delete board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Usuń tablicę"
|
||||
},
|
||||
"nabda1": {
|
||||
@@ -1863,7 +1946,7 @@
|
||||
"message": "Delete template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Usuń szablon"
|
||||
},
|
||||
"kYu0eF": {
|
||||
@@ -1916,11 +1999,18 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 45]],
|
||||
"translation": "Design"
|
||||
},
|
||||
"Odv3J6": {
|
||||
"message": "Disconnect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 223]],
|
||||
"translation": "Odłącz GitHub"
|
||||
},
|
||||
"YBBifR": {
|
||||
"message": "Disconnect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 108]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 177]],
|
||||
"translation": "Odłącz Trello"
|
||||
},
|
||||
"1sRmLC": {
|
||||
@@ -2079,7 +2169,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/BoardDropdown.tsx", 84],
|
||||
["src/views/board/components/BoardDropdown.tsx", 102],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 116]
|
||||
],
|
||||
"translation": "Edytuj URL tablicy"
|
||||
@@ -2265,6 +2355,13 @@
|
||||
],
|
||||
"translation": "Błąd podczas zmiany hasła"
|
||||
},
|
||||
"yhLUU8": {
|
||||
"message": "Error connecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 106]],
|
||||
"translation": "Błąd podczas łączenia z GitHub"
|
||||
},
|
||||
"cji2nM": {
|
||||
"message": "Error creating invite link",
|
||||
"placeholders": {},
|
||||
@@ -2304,11 +2401,18 @@
|
||||
],
|
||||
"translation": "Błąd podczas usuwania przestrzeni roboczej"
|
||||
},
|
||||
"gQ/02p": {
|
||||
"message": "Error disconnecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 129]],
|
||||
"translation": "Błąd podczas odłączania GitHub"
|
||||
},
|
||||
"lKAvEd": {
|
||||
"message": "Error disconnecting Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 60]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 86]],
|
||||
"translation": "Błąd podczas odłączania Trello"
|
||||
},
|
||||
"rarRW/": {
|
||||
@@ -2622,7 +2726,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 69],
|
||||
["src/views/auth/signup/index.tsx", 71],
|
||||
["src/views/home/components/Cta.tsx", 61],
|
||||
["src/views/home/components/Header.tsx", 106],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 29],
|
||||
@@ -2647,7 +2751,7 @@
|
||||
"0": ["isTemplate ? \"template\" : \"board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 65]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Rozpocznij, tworząc nowy {0}"
|
||||
},
|
||||
"zC8Whw": {
|
||||
@@ -2689,9 +2793,26 @@
|
||||
"message": "GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/home/components/Footer.tsx", 37]],
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 37],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 186]
|
||||
],
|
||||
"translation": "GitHub"
|
||||
},
|
||||
"PVT7q7": {
|
||||
"message": "GitHub connected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 99]],
|
||||
"translation": "GitHub połączony"
|
||||
},
|
||||
"/bBVaD": {
|
||||
"message": "GitHub disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 122]],
|
||||
"translation": "GitHub odłączony"
|
||||
},
|
||||
"7eMo+U": {
|
||||
"message": "Go Home",
|
||||
"placeholders": {},
|
||||
@@ -2863,21 +2984,27 @@
|
||||
"message": "Import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 60]],
|
||||
"origin": [["src/views/boards/index.tsx", 73]],
|
||||
"translation": "Importuj"
|
||||
},
|
||||
"2MPcep": {
|
||||
"message": "Import complete",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 191]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 229],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 381]
|
||||
],
|
||||
"translation": "Import zakończony"
|
||||
},
|
||||
"BEVzjL": {
|
||||
"message": "Import failed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 204]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 242],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 394]
|
||||
],
|
||||
"translation": "Import nie powiódł się"
|
||||
},
|
||||
"rRM7r0": {
|
||||
@@ -3299,7 +3426,7 @@
|
||||
"message": "Make template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 73]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Utwórz szablon"
|
||||
},
|
||||
"IDvohQ": {
|
||||
@@ -3432,7 +3559,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 82],
|
||||
["src/views/boards/index.tsx", 95],
|
||||
["src/views/home/components/Features.tsx", 73]
|
||||
],
|
||||
"translation": "Nowy"
|
||||
@@ -3471,7 +3598,7 @@
|
||||
"message": "New import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 322]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 513]],
|
||||
"translation": "Nowy import"
|
||||
},
|
||||
"n1GRql": {
|
||||
@@ -3550,9 +3677,16 @@
|
||||
"0": ["isTemplate ? \"templates\" : \"boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 62]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Brak {0}"
|
||||
},
|
||||
"tlhgDC": {
|
||||
"message": "No archived boards",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Brak zarchiwizowanych tablic"
|
||||
},
|
||||
"Eg99Sc": {
|
||||
"message": "No authentication methods are currently available",
|
||||
"placeholders": {},
|
||||
@@ -3564,7 +3698,7 @@
|
||||
"message": "No boards found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 242]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 432]],
|
||||
"translation": "Nie znaleziono żadnych tablic"
|
||||
},
|
||||
"OpNhRn": {
|
||||
@@ -3609,6 +3743,13 @@
|
||||
"origin": [["src/views/board/index.tsx", 527]],
|
||||
"translation": "Nie utworzono jeszcze żadnych list"
|
||||
},
|
||||
"i30J2U": {
|
||||
"message": "No projects found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 283]],
|
||||
"translation": "Nie znaleziono projektów"
|
||||
},
|
||||
"ERpq2P": {
|
||||
"message": "No results found for \"{debouncedQuery}\".",
|
||||
"placeholders": {
|
||||
@@ -3963,7 +4104,7 @@
|
||||
["src/components/DeleteLabelConfirmation.tsx", 26],
|
||||
["src/components/FeedbackModal.tsx", 41],
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/board/components/BoardDropdown.tsx", 63],
|
||||
["src/views/board/components/BoardDropdown.tsx", 65],
|
||||
["src/views/board/components/NewCardForm.tsx", 184],
|
||||
["src/views/board/components/NewListForm.tsx", 79],
|
||||
["src/views/board/components/NewTemplateForm.tsx", 61],
|
||||
@@ -3972,7 +4113,8 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 181],
|
||||
["src/views/board/index.tsx", 237],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 205],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 69],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 97],
|
||||
@@ -4178,7 +4320,7 @@
|
||||
"message": "Remove from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 92]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 121]],
|
||||
"translation": "Usuń z ulubionych"
|
||||
},
|
||||
"99VIgC": {
|
||||
@@ -4232,7 +4374,7 @@
|
||||
"message": "Removed from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 52]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"translation": "Usunięto z ulubionych"
|
||||
},
|
||||
"YVT40D": {
|
||||
@@ -4426,14 +4568,17 @@
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 274]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 315],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 464]
|
||||
],
|
||||
"translation": "Zaznacz wszystko"
|
||||
},
|
||||
"rYUZIe": {
|
||||
"message": "Select source",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 157]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Wybierz źródło"
|
||||
},
|
||||
"ppaRWv": {
|
||||
@@ -4520,7 +4665,7 @@
|
||||
"message": "Settings | Integrations",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 69]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 138]],
|
||||
"translation": "Ustawienia | Integracje"
|
||||
},
|
||||
"F/FPk/": {
|
||||
@@ -4570,8 +4715,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 34],
|
||||
["src/views/auth/signup/index.tsx", 59]
|
||||
["src/views/auth/signup/index.tsx", 36],
|
||||
["src/views/auth/signup/index.tsx", 61]
|
||||
],
|
||||
"translation": "Rejestracja | kan.bn"
|
||||
},
|
||||
@@ -4579,14 +4724,14 @@
|
||||
"message": "Sign up disabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 44]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 46]],
|
||||
"translation": "Rejestracja wyłączona"
|
||||
},
|
||||
"s6iE/c": {
|
||||
"message": "Sign up is currently disabled. Please try again later.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 47]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 49]],
|
||||
"translation": "Rejestracja jest obecnie wyłączona. Spróbuj ponownie później."
|
||||
},
|
||||
"6FDocz": {
|
||||
@@ -4809,6 +4954,20 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 34]],
|
||||
"translation": "Dziękujemy za Twoją opinię!"
|
||||
},
|
||||
"NcFrgC": {
|
||||
"message": "The board has been archived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 46]],
|
||||
"translation": "Tablica została zarchiwizowana."
|
||||
},
|
||||
"C6gv54": {
|
||||
"message": "The board has been unarchived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Tablica została przywrócona z archiwum."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5001,6 +5160,13 @@
|
||||
"origin": [["src/views/home/components/Header.tsx", 114]],
|
||||
"translation": "Przełącz menu"
|
||||
},
|
||||
"L5WQLg": {
|
||||
"message": "Token is required",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 19]],
|
||||
"translation": "Wymagany jest token"
|
||||
},
|
||||
"eEQyz+": {
|
||||
"message": "Track all card changes with detailed activity history.",
|
||||
"placeholders": {},
|
||||
@@ -5014,7 +5180,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 218],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 73]
|
||||
["src/views/settings/IntegrationsSettings.tsx", 142]
|
||||
],
|
||||
"translation": "Trello"
|
||||
},
|
||||
@@ -5022,7 +5188,7 @@
|
||||
"message": "Trello disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 53]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 79]],
|
||||
"translation": "Trello zostało odłączone"
|
||||
},
|
||||
"kxEs5t": {
|
||||
@@ -5196,7 +5362,7 @@
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 62]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 64]],
|
||||
"translation": "Nie można zaktualizować tablicy"
|
||||
},
|
||||
"XpcjLO": {
|
||||
@@ -5292,6 +5458,13 @@
|
||||
"origin": [["src/views/members/index.tsx", 65]],
|
||||
"translation": "Nie można zaktualizować roli"
|
||||
},
|
||||
"It4/FS": {
|
||||
"message": "Unarchive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Przywróć tablicę z archiwum"
|
||||
},
|
||||
"E8zYtd": {
|
||||
"message": "unassigned <0>{0}</0> from the card",
|
||||
"placeholders": {
|
||||
@@ -5671,7 +5844,7 @@
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 46],
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
["src/views/public/boards/index.tsx", 65]
|
||||
@@ -5883,9 +6056,9 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 474],
|
||||
["src/views/board/index.tsx", 532],
|
||||
["src/views/boards/components/BoardsList.tsx", 70],
|
||||
["src/views/boards/index.tsx", 46],
|
||||
["src/views/boards/index.tsx", 67]
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
],
|
||||
"translation": "Nie masz uprawnień"
|
||||
},
|
||||
@@ -5951,7 +6124,7 @@
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 192]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 382]],
|
||||
"translation": "Twoje tablice zostały zaimportowane."
|
||||
},
|
||||
"LqWW5F": {
|
||||
@@ -5968,6 +6141,27 @@
|
||||
"origin": [["src/views/card/components/AttachmentUpload.tsx", 46]],
|
||||
"translation": "Twój plik został pomyślnie przesłany."
|
||||
},
|
||||
"HcT8J4": {
|
||||
"message": "Your GitHub account has been connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 100]],
|
||||
"translation": "Twoje konto GitHub zostało połączone."
|
||||
},
|
||||
"AdxYds": {
|
||||
"message": "Your GitHub account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 123]],
|
||||
"translation": "Twoje konto GitHub zostało odłączone."
|
||||
},
|
||||
"PELbXB": {
|
||||
"message": "Your GitHub account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 220]],
|
||||
"translation": "Twoje konto GitHub jest połączone."
|
||||
},
|
||||
"Ozt2vv": {
|
||||
"message": "Your password has been changed.",
|
||||
"placeholders": {},
|
||||
@@ -5984,18 +6178,25 @@
|
||||
"origin": [["src/views/settings/components/Avatar.tsx", 190]],
|
||||
"translation": "Twoje zdjęcie profilowe zostało zaktualizowane."
|
||||
},
|
||||
"+jbXzb": {
|
||||
"message": "Your projects have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 230]],
|
||||
"translation": "Twoje projekty zostały zaimportowane."
|
||||
},
|
||||
"CJWDTP": {
|
||||
"message": "Your Trello account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 54]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"translation": "Twoje konto Trello zostało odłączone."
|
||||
},
|
||||
"WRsbHO": {
|
||||
"message": "Your Trello account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 102]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 171]],
|
||||
"translation": "Twoje konto Trello jest połączone."
|
||||
},
|
||||
"25fAUC": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -19,7 +19,7 @@
|
||||
"0": ["isTemplate ? \"Templates\" : \"Boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 40]],
|
||||
"origin": [["src/views/boards/index.tsx", 53]],
|
||||
"translation": "{0}"
|
||||
},
|
||||
"JArWcF": {
|
||||
@@ -33,8 +33,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/card/index.tsx", 309]
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/card/index.tsx", 308]
|
||||
],
|
||||
"translation": "{0} | {1}"
|
||||
},
|
||||
@@ -44,7 +44,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 56]],
|
||||
"translation": "{0} foi adicionado aos seus favoritos."
|
||||
},
|
||||
"bDI6VI": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 55]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 57]],
|
||||
"translation": "{0} foi removido dos seus favoritos."
|
||||
},
|
||||
"CJukzS": {
|
||||
@@ -80,9 +80,18 @@
|
||||
"boardCount": ["boardCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 299]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 489]],
|
||||
"translation": "{boardCount, plural, one {Importar quadro (1)} other {Importar quadros ({boardCount})}}"
|
||||
},
|
||||
"yndBF+": {
|
||||
"message": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}",
|
||||
"placeholders": {
|
||||
"projectCount": ["projectCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 341]],
|
||||
"translation": "{projectCount, plural, one {Importar projeto (1)} other {Importar projetos ({projectCount})}}"
|
||||
},
|
||||
"9lFfqv": {
|
||||
"message": "/month",
|
||||
"placeholders": {},
|
||||
@@ -185,12 +194,19 @@
|
||||
"origin": [["src/providers/keyboard-shortcuts.tsx", 56]],
|
||||
"translation": "Ações"
|
||||
},
|
||||
"F6pfE9": {
|
||||
"message": "Active",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 26]],
|
||||
"translation": "Ativo"
|
||||
},
|
||||
"XJOV1Y": {
|
||||
"message": "Activity",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 447],
|
||||
["src/views/card/index.tsx", 446],
|
||||
["src/views/public/board/CardModal.tsx", 189]
|
||||
],
|
||||
"translation": "Atividade"
|
||||
@@ -246,7 +262,7 @@
|
||||
"message": "Add description... (type '/' to open commands or '@' to mention)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/Editor.tsx", 471]],
|
||||
"origin": [["src/components/Editor.tsx", 482]],
|
||||
"translation": "Adicionar descrição... (digite '/' para abrir comandos ou '@' para mencionar)"
|
||||
},
|
||||
"abUZlY": {
|
||||
@@ -280,7 +296,7 @@
|
||||
"message": "Add to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 93]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 122]],
|
||||
"translation": "Adicionar aos favoritos"
|
||||
},
|
||||
"bmXKoX": {
|
||||
@@ -368,7 +384,7 @@
|
||||
"message": "Added to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 51]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 53]],
|
||||
"translation": "Adicionado aos favoritos"
|
||||
},
|
||||
"14Xi3Z": {
|
||||
@@ -482,14 +498,28 @@
|
||||
"message": "Already have an account? <0><1>Sign in</1></0>",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 88]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 90]],
|
||||
"translation": "Já tem uma conta? <0><1>Entrar</1></0>"
|
||||
},
|
||||
"j1+HPc": {
|
||||
"message": "An error occurred while connecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 107]],
|
||||
"translation": "Ocorreu um erro ao conectar sua conta do GitHub."
|
||||
},
|
||||
"Dz63YI": {
|
||||
"message": "An error occurred while disconnecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 130]],
|
||||
"translation": "Ocorreu um erro ao desconectar sua conta do GitHub."
|
||||
},
|
||||
"WmPhYW": {
|
||||
"message": "An error occurred while disconnecting your Trello account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 61]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 87]],
|
||||
"translation": "Ocorreu um erro ao desconectar sua conta do Trello."
|
||||
},
|
||||
"ZXSPJt": {
|
||||
@@ -574,6 +604,20 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 46]],
|
||||
"translation": "Aprovação"
|
||||
},
|
||||
"aKJHG+": {
|
||||
"message": "Archive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Arquivar quadro"
|
||||
},
|
||||
"TdfEV7": {
|
||||
"message": "Archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 27]],
|
||||
"translation": "Arquivado"
|
||||
},
|
||||
"lo8xBK": {
|
||||
"message": "Are you sure want to remove {entityLabel}?",
|
||||
"placeholders": {
|
||||
@@ -770,7 +814,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/card/index.tsx", 309],
|
||||
["src/views/card/index.tsx", 308],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
"translation": "Quadro"
|
||||
@@ -785,6 +829,13 @@
|
||||
],
|
||||
"translation": "Análise do quadro"
|
||||
},
|
||||
"i0ZMQl": {
|
||||
"message": "Board archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Quadro arquivado"
|
||||
},
|
||||
"wewm3j": {
|
||||
"message": "Board name cannot exceed 100 characters",
|
||||
"placeholders": {},
|
||||
@@ -815,6 +866,13 @@
|
||||
],
|
||||
"translation": "Modelos de quadro"
|
||||
},
|
||||
"tbNcu4": {
|
||||
"message": "Board unarchived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Quadro desarquivado"
|
||||
},
|
||||
"Xid3K6": {
|
||||
"message": "Board URL can only contain letters, numbers, and hyphens",
|
||||
"placeholders": {},
|
||||
@@ -873,6 +931,13 @@
|
||||
],
|
||||
"translation": "Quadros"
|
||||
},
|
||||
"0RE1AJ": {
|
||||
"message": "Boards you archive will appear here.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Os quadros que você arquivar aparecerão aqui."
|
||||
},
|
||||
"ZDo4HN": {
|
||||
"message": "Brainstorming",
|
||||
"placeholders": {},
|
||||
@@ -1163,7 +1228,7 @@
|
||||
"message": "Card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 309]],
|
||||
"origin": [["src/views/card/index.tsx", 308]],
|
||||
"translation": "Cartão"
|
||||
},
|
||||
"fEY2vP": {
|
||||
@@ -1171,8 +1236,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 355],
|
||||
["src/views/card/index.tsx", 392]
|
||||
["src/views/card/index.tsx", 354],
|
||||
["src/views/card/index.tsx", 391]
|
||||
],
|
||||
"translation": "Cartão não encontrado"
|
||||
},
|
||||
@@ -1237,7 +1302,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 43],
|
||||
["src/views/auth/signup/index.tsx", 69]
|
||||
["src/views/auth/signup/index.tsx", 71]
|
||||
],
|
||||
"translation": "Verifique sua caixa de entrada"
|
||||
},
|
||||
@@ -1305,7 +1370,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 48],
|
||||
["src/views/auth/signup/index.tsx", 74]
|
||||
["src/views/auth/signup/index.tsx", 76]
|
||||
],
|
||||
"translation": "Clique no link que enviamos para {magicLinkRecipient} para fazer login."
|
||||
},
|
||||
@@ -1314,7 +1379,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 346],
|
||||
["src/views/card/index.tsx", 345],
|
||||
["src/views/members/components/EditMemberPermissionsModal.tsx", 172],
|
||||
["src/views/settings/components/NewApiKeyModal.tsx", 136]
|
||||
],
|
||||
@@ -1431,14 +1496,25 @@
|
||||
],
|
||||
"translation": "Confirme sua nova senha"
|
||||
},
|
||||
"iSLIjg": {
|
||||
"message": "Connect",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Conectar"
|
||||
},
|
||||
"3jod3l": {
|
||||
"message": "Connect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 212]],
|
||||
"translation": "Conectar GitHub"
|
||||
},
|
||||
"nk7caK": {
|
||||
"message": "Connect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 157],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 93]
|
||||
],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 162]],
|
||||
"translation": "Conectar Trello"
|
||||
},
|
||||
"sDLCvT": {
|
||||
@@ -1448,11 +1524,18 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 122]],
|
||||
"translation": "Conecte suas ferramentas favoritas para otimizar seu fluxo de trabalho."
|
||||
},
|
||||
"MCIXdZ": {
|
||||
"message": "Connect your GitHub account to import projects.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 191]],
|
||||
"translation": "Conecte sua conta do GitHub para importar projetos."
|
||||
},
|
||||
"5eZwRW": {
|
||||
"message": "Connect your Trello account to import boards.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 149]],
|
||||
"translation": "Conecte sua conta do Trello para importar quadros."
|
||||
},
|
||||
"jfC/xh": {
|
||||
@@ -1612,8 +1695,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/BoardsList.tsx", 79],
|
||||
["src/views/boards/index.tsx", 28]
|
||||
["src/views/boards/components/BoardsList.tsx", 80],
|
||||
["src/views/boards/index.tsx", 41]
|
||||
],
|
||||
"translation": "Criar novo {0}"
|
||||
},
|
||||
@@ -1835,7 +1918,7 @@
|
||||
"message": "Delete board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Excluir quadro"
|
||||
},
|
||||
"nabda1": {
|
||||
@@ -1863,7 +1946,7 @@
|
||||
"message": "Delete template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Excluir modelo"
|
||||
},
|
||||
"kYu0eF": {
|
||||
@@ -1916,11 +1999,18 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 45]],
|
||||
"translation": "Design"
|
||||
},
|
||||
"Odv3J6": {
|
||||
"message": "Disconnect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 223]],
|
||||
"translation": "Desconectar GitHub"
|
||||
},
|
||||
"YBBifR": {
|
||||
"message": "Disconnect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 108]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 177]],
|
||||
"translation": "Desconectar Trello"
|
||||
},
|
||||
"1sRmLC": {
|
||||
@@ -2079,7 +2169,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/BoardDropdown.tsx", 84],
|
||||
["src/views/board/components/BoardDropdown.tsx", 102],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 116]
|
||||
],
|
||||
"translation": "Editar URL do quadro"
|
||||
@@ -2265,6 +2355,13 @@
|
||||
],
|
||||
"translation": "Erro ao alterar senha"
|
||||
},
|
||||
"yhLUU8": {
|
||||
"message": "Error connecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 106]],
|
||||
"translation": "Erro ao conectar GitHub"
|
||||
},
|
||||
"cji2nM": {
|
||||
"message": "Error creating invite link",
|
||||
"placeholders": {},
|
||||
@@ -2304,11 +2401,18 @@
|
||||
],
|
||||
"translation": "Erro ao excluir workspace"
|
||||
},
|
||||
"gQ/02p": {
|
||||
"message": "Error disconnecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 129]],
|
||||
"translation": "Erro ao desconectar GitHub"
|
||||
},
|
||||
"lKAvEd": {
|
||||
"message": "Error disconnecting Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 60]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 86]],
|
||||
"translation": "Erro ao desconectar Trello"
|
||||
},
|
||||
"rarRW/": {
|
||||
@@ -2622,7 +2726,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 69],
|
||||
["src/views/auth/signup/index.tsx", 71],
|
||||
["src/views/home/components/Cta.tsx", 61],
|
||||
["src/views/home/components/Header.tsx", 106],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 29],
|
||||
@@ -2647,7 +2751,7 @@
|
||||
"0": ["isTemplate ? \"template\" : \"board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 65]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Comece criando um novo {0}"
|
||||
},
|
||||
"zC8Whw": {
|
||||
@@ -2689,9 +2793,26 @@
|
||||
"message": "GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/home/components/Footer.tsx", 37]],
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 37],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 186]
|
||||
],
|
||||
"translation": "GitHub"
|
||||
},
|
||||
"PVT7q7": {
|
||||
"message": "GitHub connected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 99]],
|
||||
"translation": "GitHub conectado"
|
||||
},
|
||||
"/bBVaD": {
|
||||
"message": "GitHub disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 122]],
|
||||
"translation": "GitHub desconectado"
|
||||
},
|
||||
"7eMo+U": {
|
||||
"message": "Go Home",
|
||||
"placeholders": {},
|
||||
@@ -2863,21 +2984,27 @@
|
||||
"message": "Import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 60]],
|
||||
"origin": [["src/views/boards/index.tsx", 73]],
|
||||
"translation": "Importar"
|
||||
},
|
||||
"2MPcep": {
|
||||
"message": "Import complete",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 191]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 229],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 381]
|
||||
],
|
||||
"translation": "Importação concluída"
|
||||
},
|
||||
"BEVzjL": {
|
||||
"message": "Import failed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 204]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 242],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 394]
|
||||
],
|
||||
"translation": "Falha na importação"
|
||||
},
|
||||
"rRM7r0": {
|
||||
@@ -3299,7 +3426,7 @@
|
||||
"message": "Make template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 73]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Criar modelo"
|
||||
},
|
||||
"IDvohQ": {
|
||||
@@ -3432,7 +3559,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 82],
|
||||
["src/views/boards/index.tsx", 95],
|
||||
["src/views/home/components/Features.tsx", 73]
|
||||
],
|
||||
"translation": "Novo"
|
||||
@@ -3471,7 +3598,7 @@
|
||||
"message": "New import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 322]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 513]],
|
||||
"translation": "Nova importação"
|
||||
},
|
||||
"n1GRql": {
|
||||
@@ -3550,9 +3677,16 @@
|
||||
"0": ["isTemplate ? \"templates\" : \"boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 62]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Nenhum {0}"
|
||||
},
|
||||
"tlhgDC": {
|
||||
"message": "No archived boards",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Nenhum quadro arquivado"
|
||||
},
|
||||
"Eg99Sc": {
|
||||
"message": "No authentication methods are currently available",
|
||||
"placeholders": {},
|
||||
@@ -3564,7 +3698,7 @@
|
||||
"message": "No boards found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 242]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 432]],
|
||||
"translation": "Nenhum quadro encontrado"
|
||||
},
|
||||
"OpNhRn": {
|
||||
@@ -3609,6 +3743,13 @@
|
||||
"origin": [["src/views/board/index.tsx", 527]],
|
||||
"translation": "Nenhuma lista foi criada ainda"
|
||||
},
|
||||
"i30J2U": {
|
||||
"message": "No projects found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 283]],
|
||||
"translation": "Nenhum projeto encontrado"
|
||||
},
|
||||
"ERpq2P": {
|
||||
"message": "No results found for \"{debouncedQuery}\".",
|
||||
"placeholders": {
|
||||
@@ -3963,7 +4104,7 @@
|
||||
["src/components/DeleteLabelConfirmation.tsx", 26],
|
||||
["src/components/FeedbackModal.tsx", 41],
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/board/components/BoardDropdown.tsx", 63],
|
||||
["src/views/board/components/BoardDropdown.tsx", 65],
|
||||
["src/views/board/components/NewCardForm.tsx", 184],
|
||||
["src/views/board/components/NewListForm.tsx", 79],
|
||||
["src/views/board/components/NewTemplateForm.tsx", 61],
|
||||
@@ -3972,7 +4113,8 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 181],
|
||||
["src/views/board/index.tsx", 237],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 205],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 69],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 97],
|
||||
@@ -4178,7 +4320,7 @@
|
||||
"message": "Remove from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 92]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 121]],
|
||||
"translation": "Remover dos favoritos"
|
||||
},
|
||||
"99VIgC": {
|
||||
@@ -4232,7 +4374,7 @@
|
||||
"message": "Removed from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 52]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"translation": "Removido dos favoritos"
|
||||
},
|
||||
"YVT40D": {
|
||||
@@ -4426,14 +4568,17 @@
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 274]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 315],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 464]
|
||||
],
|
||||
"translation": "Selecionar tudo"
|
||||
},
|
||||
"rYUZIe": {
|
||||
"message": "Select source",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 157]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Selecionar origem"
|
||||
},
|
||||
"ppaRWv": {
|
||||
@@ -4520,7 +4665,7 @@
|
||||
"message": "Settings | Integrations",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 69]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 138]],
|
||||
"translation": "Configurações | Integrações"
|
||||
},
|
||||
"F/FPk/": {
|
||||
@@ -4570,8 +4715,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 34],
|
||||
["src/views/auth/signup/index.tsx", 59]
|
||||
["src/views/auth/signup/index.tsx", 36],
|
||||
["src/views/auth/signup/index.tsx", 61]
|
||||
],
|
||||
"translation": "Cadastrar | kan.bn"
|
||||
},
|
||||
@@ -4579,14 +4724,14 @@
|
||||
"message": "Sign up disabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 44]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 46]],
|
||||
"translation": "Cadastro desabilitado"
|
||||
},
|
||||
"s6iE/c": {
|
||||
"message": "Sign up is currently disabled. Please try again later.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 47]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 49]],
|
||||
"translation": "O cadastro está temporariamente desabilitado. Por favor, tente novamente mais tarde."
|
||||
},
|
||||
"6FDocz": {
|
||||
@@ -4809,6 +4954,20 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 34]],
|
||||
"translation": "Obrigado pelo seu feedback!"
|
||||
},
|
||||
"NcFrgC": {
|
||||
"message": "The board has been archived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 46]],
|
||||
"translation": "O quadro foi arquivado."
|
||||
},
|
||||
"C6gv54": {
|
||||
"message": "The board has been unarchived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "O quadro foi desarquivado."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5001,6 +5160,13 @@
|
||||
"origin": [["src/views/home/components/Header.tsx", 114]],
|
||||
"translation": "Alternar menu"
|
||||
},
|
||||
"L5WQLg": {
|
||||
"message": "Token is required",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 19]],
|
||||
"translation": "Token é obrigatório"
|
||||
},
|
||||
"eEQyz+": {
|
||||
"message": "Track all card changes with detailed activity history.",
|
||||
"placeholders": {},
|
||||
@@ -5014,7 +5180,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 218],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 73]
|
||||
["src/views/settings/IntegrationsSettings.tsx", 142]
|
||||
],
|
||||
"translation": "Trello"
|
||||
},
|
||||
@@ -5022,7 +5188,7 @@
|
||||
"message": "Trello disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 53]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 79]],
|
||||
"translation": "Trello desconectado"
|
||||
},
|
||||
"kxEs5t": {
|
||||
@@ -5196,7 +5362,7 @@
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 62]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 64]],
|
||||
"translation": "Não foi possível atualizar o quadro"
|
||||
},
|
||||
"XpcjLO": {
|
||||
@@ -5292,6 +5458,13 @@
|
||||
"origin": [["src/views/members/index.tsx", 65]],
|
||||
"translation": "Não foi possível atualizar a função"
|
||||
},
|
||||
"It4/FS": {
|
||||
"message": "Unarchive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Desarquivar quadro"
|
||||
},
|
||||
"E8zYtd": {
|
||||
"message": "unassigned <0>{0}</0> from the card",
|
||||
"placeholders": {
|
||||
@@ -5671,7 +5844,7 @@
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 46],
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
["src/views/public/boards/index.tsx", 65]
|
||||
@@ -5883,9 +6056,9 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 474],
|
||||
["src/views/board/index.tsx", 532],
|
||||
["src/views/boards/components/BoardsList.tsx", 70],
|
||||
["src/views/boards/index.tsx", 46],
|
||||
["src/views/boards/index.tsx", 67]
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
],
|
||||
"translation": "Você não tem permissão"
|
||||
},
|
||||
@@ -5951,7 +6124,7 @@
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 192]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 382]],
|
||||
"translation": "Seus quadros foram importados."
|
||||
},
|
||||
"LqWW5F": {
|
||||
@@ -5968,6 +6141,27 @@
|
||||
"origin": [["src/views/card/components/AttachmentUpload.tsx", 46]],
|
||||
"translation": "Seu arquivo foi enviado com sucesso."
|
||||
},
|
||||
"HcT8J4": {
|
||||
"message": "Your GitHub account has been connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 100]],
|
||||
"translation": "Sua conta do GitHub foi conectada."
|
||||
},
|
||||
"AdxYds": {
|
||||
"message": "Your GitHub account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 123]],
|
||||
"translation": "Sua conta do GitHub foi desconectada."
|
||||
},
|
||||
"PELbXB": {
|
||||
"message": "Your GitHub account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 220]],
|
||||
"translation": "Sua conta do GitHub está conectada."
|
||||
},
|
||||
"Ozt2vv": {
|
||||
"message": "Your password has been changed.",
|
||||
"placeholders": {},
|
||||
@@ -5984,18 +6178,25 @@
|
||||
"origin": [["src/views/settings/components/Avatar.tsx", 190]],
|
||||
"translation": "Sua imagem de perfil foi atualizada."
|
||||
},
|
||||
"+jbXzb": {
|
||||
"message": "Your projects have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 230]],
|
||||
"translation": "Seus projetos foram importados."
|
||||
},
|
||||
"CJWDTP": {
|
||||
"message": "Your Trello account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 54]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"translation": "Sua conta do Trello foi desconectada."
|
||||
},
|
||||
"WRsbHO": {
|
||||
"message": "Your Trello account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 102]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 171]],
|
||||
"translation": "Sua conta do Trello está conectada."
|
||||
},
|
||||
"25fAUC": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
2899
apps/web/src/locales/ptbr/messages.po
Normal file
2899
apps/web/src/locales/ptbr/messages.po
Normal file
File diff suppressed because it is too large
Load Diff
1
apps/web/src/locales/ptbr/messages.ts
Normal file
1
apps/web/src/locales/ptbr/messages.ts
Normal file
File diff suppressed because one or more lines are too long
@@ -19,7 +19,7 @@
|
||||
"0": ["isTemplate ? \"Templates\" : \"Boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 40]],
|
||||
"origin": [["src/views/boards/index.tsx", 53]],
|
||||
"translation": "{0}"
|
||||
},
|
||||
"JArWcF": {
|
||||
@@ -33,8 +33,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/card/index.tsx", 309]
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/card/index.tsx", 308]
|
||||
],
|
||||
"translation": "{0} | {1}"
|
||||
},
|
||||
@@ -44,7 +44,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 56]],
|
||||
"translation": "{0} добавлен в избранное."
|
||||
},
|
||||
"bDI6VI": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"0": ["boardName ?? \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 55]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 57]],
|
||||
"translation": "{0} удалён из избранного."
|
||||
},
|
||||
"CJukzS": {
|
||||
@@ -80,9 +80,18 @@
|
||||
"boardCount": ["boardCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 299]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 489]],
|
||||
"translation": "{boardCount, plural, one {Импортировать доску (1)} few {Импортировать доски ({boardCount})} many {Импортировать досок ({boardCount})} other {Импортировать доски ({boardCount})}}"
|
||||
},
|
||||
"yndBF+": {
|
||||
"message": "{projectCount, plural, one {Import project (1)} other {Import projects ({projectCount})}}",
|
||||
"placeholders": {
|
||||
"projectCount": ["projectCount"]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 341]],
|
||||
"translation": "{projectCount, plural, one {Импортировать проект (1)} few {Импортировать проекта ({projectCount})} many {Импортировать проектов ({projectCount})} other {Импортировать проекта ({projectCount})}}"
|
||||
},
|
||||
"9lFfqv": {
|
||||
"message": "/month",
|
||||
"placeholders": {},
|
||||
@@ -185,12 +194,19 @@
|
||||
"origin": [["src/providers/keyboard-shortcuts.tsx", 56]],
|
||||
"translation": "Действия"
|
||||
},
|
||||
"F6pfE9": {
|
||||
"message": "Active",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 26]],
|
||||
"translation": "Активно"
|
||||
},
|
||||
"XJOV1Y": {
|
||||
"message": "Activity",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 447],
|
||||
["src/views/card/index.tsx", 446],
|
||||
["src/views/public/board/CardModal.tsx", 189]
|
||||
],
|
||||
"translation": "Активность"
|
||||
@@ -246,7 +262,7 @@
|
||||
"message": "Add description... (type '/' to open commands or '@' to mention)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/Editor.tsx", 471]],
|
||||
"origin": [["src/components/Editor.tsx", 482]],
|
||||
"translation": "Добавить описание... (введите '/' для открытия команд или '@' для упоминания)"
|
||||
},
|
||||
"abUZlY": {
|
||||
@@ -280,7 +296,7 @@
|
||||
"message": "Add to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 93]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 122]],
|
||||
"translation": "Добавить в избранное"
|
||||
},
|
||||
"bmXKoX": {
|
||||
@@ -368,7 +384,7 @@
|
||||
"message": "Added to favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 51]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 53]],
|
||||
"translation": "Добавлено в избранное"
|
||||
},
|
||||
"14Xi3Z": {
|
||||
@@ -482,14 +498,28 @@
|
||||
"message": "Already have an account? <0><1>Sign in</1></0>",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 88]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 90]],
|
||||
"translation": "Уже есть аккаунт? <0><1>Войти</1></0>"
|
||||
},
|
||||
"j1+HPc": {
|
||||
"message": "An error occurred while connecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 107]],
|
||||
"translation": "Произошла ошибка при подключении вашего аккаунта GitHub."
|
||||
},
|
||||
"Dz63YI": {
|
||||
"message": "An error occurred while disconnecting your GitHub account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 130]],
|
||||
"translation": "Произошла ошибка при отключении вашего аккаунта GitHub."
|
||||
},
|
||||
"WmPhYW": {
|
||||
"message": "An error occurred while disconnecting your Trello account.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 61]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 87]],
|
||||
"translation": "Произошла ошибка при отключении вашей учетной записи Trello."
|
||||
},
|
||||
"ZXSPJt": {
|
||||
@@ -574,6 +604,20 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 46]],
|
||||
"translation": "Одобрение"
|
||||
},
|
||||
"aKJHG+": {
|
||||
"message": "Archive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Архивировать доску"
|
||||
},
|
||||
"TdfEV7": {
|
||||
"message": "Archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 27]],
|
||||
"translation": "В архиве"
|
||||
},
|
||||
"lo8xBK": {
|
||||
"message": "Are you sure want to remove {entityLabel}?",
|
||||
"placeholders": {
|
||||
@@ -770,7 +814,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/card/index.tsx", 309],
|
||||
["src/views/card/index.tsx", 308],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
"translation": "Доска"
|
||||
@@ -785,6 +829,13 @@
|
||||
],
|
||||
"translation": "Аналитика доски"
|
||||
},
|
||||
"i0ZMQl": {
|
||||
"message": "Board archived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Доска архивирована"
|
||||
},
|
||||
"wewm3j": {
|
||||
"message": "Board name cannot exceed 100 characters",
|
||||
"placeholders": {},
|
||||
@@ -815,6 +866,13 @@
|
||||
],
|
||||
"translation": "Шаблоны досок"
|
||||
},
|
||||
"tbNcu4": {
|
||||
"message": "Board unarchived",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 44]],
|
||||
"translation": "Доска восстановлена из архива"
|
||||
},
|
||||
"Xid3K6": {
|
||||
"message": "Board URL can only contain letters, numbers, and hyphens",
|
||||
"placeholders": {},
|
||||
@@ -873,6 +931,13 @@
|
||||
],
|
||||
"translation": "Доски"
|
||||
},
|
||||
"0RE1AJ": {
|
||||
"message": "Boards you archive will appear here.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Здесь будут отображаться архивированные вами доски."
|
||||
},
|
||||
"ZDo4HN": {
|
||||
"message": "Brainstorming",
|
||||
"placeholders": {},
|
||||
@@ -1163,7 +1228,7 @@
|
||||
"message": "Card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 309]],
|
||||
"origin": [["src/views/card/index.tsx", 308]],
|
||||
"translation": "Карточка"
|
||||
},
|
||||
"fEY2vP": {
|
||||
@@ -1171,8 +1236,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 355],
|
||||
["src/views/card/index.tsx", 392]
|
||||
["src/views/card/index.tsx", 354],
|
||||
["src/views/card/index.tsx", 391]
|
||||
],
|
||||
"translation": "Карточка не найдена"
|
||||
},
|
||||
@@ -1237,7 +1302,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 43],
|
||||
["src/views/auth/signup/index.tsx", 69]
|
||||
["src/views/auth/signup/index.tsx", 71]
|
||||
],
|
||||
"translation": "Проверьте свой почтовый ящик"
|
||||
},
|
||||
@@ -1305,7 +1370,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/login/index.tsx", 48],
|
||||
["src/views/auth/signup/index.tsx", 74]
|
||||
["src/views/auth/signup/index.tsx", 76]
|
||||
],
|
||||
"translation": "Перейдите по ссылке, которую мы отправили на {magicLinkRecipient}, чтобы войти."
|
||||
},
|
||||
@@ -1314,7 +1379,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/index.tsx", 346],
|
||||
["src/views/card/index.tsx", 345],
|
||||
["src/views/members/components/EditMemberPermissionsModal.tsx", 172],
|
||||
["src/views/settings/components/NewApiKeyModal.tsx", 136]
|
||||
],
|
||||
@@ -1431,14 +1496,25 @@
|
||||
],
|
||||
"translation": "Подтвердите новый пароль"
|
||||
},
|
||||
"iSLIjg": {
|
||||
"message": "Connect",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Подключить"
|
||||
},
|
||||
"3jod3l": {
|
||||
"message": "Connect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 212]],
|
||||
"translation": "Подключить GitHub"
|
||||
},
|
||||
"nk7caK": {
|
||||
"message": "Connect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 157],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 93]
|
||||
],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 162]],
|
||||
"translation": "Подключить Trello"
|
||||
},
|
||||
"sDLCvT": {
|
||||
@@ -1448,11 +1524,18 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 122]],
|
||||
"translation": "Подключите любимые инструменты, чтобы упростить рабочий процесс."
|
||||
},
|
||||
"MCIXdZ": {
|
||||
"message": "Connect your GitHub account to import projects.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 191]],
|
||||
"translation": "Подключите свой аккаунт GitHub, чтобы импортировать проекты."
|
||||
},
|
||||
"5eZwRW": {
|
||||
"message": "Connect your Trello account to import boards.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 149]],
|
||||
"translation": "Подключите ваш аккаунт Trello для импорта досок."
|
||||
},
|
||||
"jfC/xh": {
|
||||
@@ -1612,8 +1695,8 @@
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/components/BoardsList.tsx", 79],
|
||||
["src/views/boards/index.tsx", 28]
|
||||
["src/views/boards/components/BoardsList.tsx", 80],
|
||||
["src/views/boards/index.tsx", 41]
|
||||
],
|
||||
"translation": "Создать новый {0}"
|
||||
},
|
||||
@@ -1835,7 +1918,7 @@
|
||||
"message": "Delete board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Удалить доску"
|
||||
},
|
||||
"nabda1": {
|
||||
@@ -1863,7 +1946,7 @@
|
||||
"message": "Delete template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 104]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 133]],
|
||||
"translation": "Удалить шаблон"
|
||||
},
|
||||
"kYu0eF": {
|
||||
@@ -1916,11 +1999,18 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 45]],
|
||||
"translation": "Дизайн"
|
||||
},
|
||||
"Odv3J6": {
|
||||
"message": "Disconnect GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 223]],
|
||||
"translation": "Отключить GitHub"
|
||||
},
|
||||
"YBBifR": {
|
||||
"message": "Disconnect Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 108]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 177]],
|
||||
"translation": "Отключить Trello"
|
||||
},
|
||||
"1sRmLC": {
|
||||
@@ -2079,7 +2169,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/BoardDropdown.tsx", 84],
|
||||
["src/views/board/components/BoardDropdown.tsx", 102],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 116]
|
||||
],
|
||||
"translation": "Изменить URL доски"
|
||||
@@ -2265,6 +2355,13 @@
|
||||
],
|
||||
"translation": "Ошибка при смене пароля"
|
||||
},
|
||||
"yhLUU8": {
|
||||
"message": "Error connecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 106]],
|
||||
"translation": "Ошибка подключения GitHub"
|
||||
},
|
||||
"cji2nM": {
|
||||
"message": "Error creating invite link",
|
||||
"placeholders": {},
|
||||
@@ -2304,11 +2401,18 @@
|
||||
],
|
||||
"translation": "Ошибка при удалении рабочего пространства"
|
||||
},
|
||||
"gQ/02p": {
|
||||
"message": "Error disconnecting GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 129]],
|
||||
"translation": "Ошибка при отключении GitHub"
|
||||
},
|
||||
"lKAvEd": {
|
||||
"message": "Error disconnecting Trello",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 60]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 86]],
|
||||
"translation": "Ошибка при отключении Trello"
|
||||
},
|
||||
"rarRW/": {
|
||||
@@ -2622,7 +2726,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 69],
|
||||
["src/views/auth/signup/index.tsx", 71],
|
||||
["src/views/home/components/Cta.tsx", 61],
|
||||
["src/views/home/components/Header.tsx", 106],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 29],
|
||||
@@ -2647,7 +2751,7 @@
|
||||
"0": ["isTemplate ? \"template\" : \"board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 65]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 66]],
|
||||
"translation": "Начните с создания нового {0}"
|
||||
},
|
||||
"zC8Whw": {
|
||||
@@ -2689,9 +2793,26 @@
|
||||
"message": "GitHub",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/home/components/Footer.tsx", 37]],
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 37],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 186]
|
||||
],
|
||||
"translation": "GitHub"
|
||||
},
|
||||
"PVT7q7": {
|
||||
"message": "GitHub connected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 99]],
|
||||
"translation": "GitHub подключён"
|
||||
},
|
||||
"/bBVaD": {
|
||||
"message": "GitHub disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 122]],
|
||||
"translation": "GitHub отключён"
|
||||
},
|
||||
"7eMo+U": {
|
||||
"message": "Go Home",
|
||||
"placeholders": {},
|
||||
@@ -2863,21 +2984,27 @@
|
||||
"message": "Import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/index.tsx", 60]],
|
||||
"origin": [["src/views/boards/index.tsx", 73]],
|
||||
"translation": "Импорт"
|
||||
},
|
||||
"2MPcep": {
|
||||
"message": "Import complete",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 191]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 229],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 381]
|
||||
],
|
||||
"translation": "Импорт завершён"
|
||||
},
|
||||
"BEVzjL": {
|
||||
"message": "Import failed",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 204]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 242],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 394]
|
||||
],
|
||||
"translation": "Ошибка импорта"
|
||||
},
|
||||
"rRM7r0": {
|
||||
@@ -3299,7 +3426,7 @@
|
||||
"message": "Make template",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 73]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Создать шаблон"
|
||||
},
|
||||
"IDvohQ": {
|
||||
@@ -3432,7 +3559,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/boards/index.tsx", 82],
|
||||
["src/views/boards/index.tsx", 95],
|
||||
["src/views/home/components/Features.tsx", 73]
|
||||
],
|
||||
"translation": "Новый"
|
||||
@@ -3471,7 +3598,7 @@
|
||||
"message": "New import",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 322]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 513]],
|
||||
"translation": "Новый импорт"
|
||||
},
|
||||
"n1GRql": {
|
||||
@@ -3550,9 +3677,16 @@
|
||||
"0": ["isTemplate ? \"templates\" : \"boards\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 62]],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Нет {0}"
|
||||
},
|
||||
"tlhgDC": {
|
||||
"message": "No archived boards",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/BoardsList.tsx", 63]],
|
||||
"translation": "Нет архивированных досок"
|
||||
},
|
||||
"Eg99Sc": {
|
||||
"message": "No authentication methods are currently available",
|
||||
"placeholders": {},
|
||||
@@ -3564,7 +3698,7 @@
|
||||
"message": "No boards found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 242]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 432]],
|
||||
"translation": "Доски не найдены"
|
||||
},
|
||||
"OpNhRn": {
|
||||
@@ -3609,6 +3743,13 @@
|
||||
"origin": [["src/views/board/index.tsx", 527]],
|
||||
"translation": "Списки ещё не созданы"
|
||||
},
|
||||
"i30J2U": {
|
||||
"message": "No projects found",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 283]],
|
||||
"translation": "Проекты не найдены"
|
||||
},
|
||||
"ERpq2P": {
|
||||
"message": "No results found for \"{debouncedQuery}\".",
|
||||
"placeholders": {
|
||||
@@ -3963,7 +4104,7 @@
|
||||
["src/components/DeleteLabelConfirmation.tsx", 26],
|
||||
["src/components/FeedbackModal.tsx", 41],
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/board/components/BoardDropdown.tsx", 63],
|
||||
["src/views/board/components/BoardDropdown.tsx", 65],
|
||||
["src/views/board/components/NewCardForm.tsx", 184],
|
||||
["src/views/board/components/NewListForm.tsx", 79],
|
||||
["src/views/board/components/NewTemplateForm.tsx", 61],
|
||||
@@ -3972,7 +4113,8 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 181],
|
||||
["src/views/board/index.tsx", 237],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 205],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 69],
|
||||
["src/views/card/components/ChecklistItemRow.tsx", 97],
|
||||
@@ -4178,7 +4320,7 @@
|
||||
"message": "Remove from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 92]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 121]],
|
||||
"translation": "Удалить из избранного"
|
||||
},
|
||||
"99VIgC": {
|
||||
@@ -4232,7 +4374,7 @@
|
||||
"message": "Removed from favorites",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 52]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 54]],
|
||||
"translation": "Удалено из избранного"
|
||||
},
|
||||
"YVT40D": {
|
||||
@@ -4426,14 +4568,17 @@
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 274]],
|
||||
"origin": [
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 315],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 464]
|
||||
],
|
||||
"translation": "Выбрать всё"
|
||||
},
|
||||
"rYUZIe": {
|
||||
"message": "Select source",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 157]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 195]],
|
||||
"translation": "Выбрать источник"
|
||||
},
|
||||
"ppaRWv": {
|
||||
@@ -4520,7 +4665,7 @@
|
||||
"message": "Settings | Integrations",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 69]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 138]],
|
||||
"translation": "Настройки | Интеграции"
|
||||
},
|
||||
"F/FPk/": {
|
||||
@@ -4570,8 +4715,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/auth/signup/index.tsx", 34],
|
||||
["src/views/auth/signup/index.tsx", 59]
|
||||
["src/views/auth/signup/index.tsx", 36],
|
||||
["src/views/auth/signup/index.tsx", 61]
|
||||
],
|
||||
"translation": "Регистрация | kan.bn"
|
||||
},
|
||||
@@ -4579,14 +4724,14 @@
|
||||
"message": "Sign up disabled",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 44]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 46]],
|
||||
"translation": "Регистрация отключена"
|
||||
},
|
||||
"s6iE/c": {
|
||||
"message": "Sign up is currently disabled. Please try again later.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 47]],
|
||||
"origin": [["src/views/auth/signup/index.tsx", 49]],
|
||||
"translation": "Регистрация сейчас недоступна. Пожалуйста, попробуйте позже."
|
||||
},
|
||||
"6FDocz": {
|
||||
@@ -4809,6 +4954,20 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 34]],
|
||||
"translation": "Спасибо за ваш отзыв!"
|
||||
},
|
||||
"NcFrgC": {
|
||||
"message": "The board has been archived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 46]],
|
||||
"translation": "Доска была архивирована."
|
||||
},
|
||||
"C6gv54": {
|
||||
"message": "The board has been unarchived.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Доска была восстановлена из архива."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5001,6 +5160,13 @@
|
||||
"origin": [["src/views/home/components/Header.tsx", 114]],
|
||||
"translation": "Переключить меню"
|
||||
},
|
||||
"L5WQLg": {
|
||||
"message": "Token is required",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 19]],
|
||||
"translation": "Требуется токен"
|
||||
},
|
||||
"eEQyz+": {
|
||||
"message": "Track all card changes with detailed activity history.",
|
||||
"placeholders": {},
|
||||
@@ -5014,7 +5180,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 218],
|
||||
["src/views/settings/IntegrationsSettings.tsx", 73]
|
||||
["src/views/settings/IntegrationsSettings.tsx", 142]
|
||||
],
|
||||
"translation": "Trello"
|
||||
},
|
||||
@@ -5022,7 +5188,7 @@
|
||||
"message": "Trello disconnected",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 53]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 79]],
|
||||
"translation": "Trello отключён"
|
||||
},
|
||||
"kxEs5t": {
|
||||
@@ -5196,7 +5362,7 @@
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 62]],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 64]],
|
||||
"translation": "Не удалось обновить доску"
|
||||
},
|
||||
"XpcjLO": {
|
||||
@@ -5292,6 +5458,13 @@
|
||||
"origin": [["src/views/members/index.tsx", 65]],
|
||||
"translation": "Не удалось обновить роль"
|
||||
},
|
||||
"It4/FS": {
|
||||
"message": "Unarchive board",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 111]],
|
||||
"translation": "Восстановить доску из архива"
|
||||
},
|
||||
"E8zYtd": {
|
||||
"message": "unassigned <0>{0}</0> from the card",
|
||||
"placeholders": {
|
||||
@@ -5671,7 +5844,7 @@
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 46],
|
||||
["src/views/board/index.tsx", 400],
|
||||
["src/views/boards/index.tsx", 35],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
["src/views/public/boards/index.tsx", 65]
|
||||
@@ -5883,9 +6056,9 @@
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 474],
|
||||
["src/views/board/index.tsx", 532],
|
||||
["src/views/boards/components/BoardsList.tsx", 70],
|
||||
["src/views/boards/index.tsx", 46],
|
||||
["src/views/boards/index.tsx", 67]
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
],
|
||||
"translation": "У вас нет прав доступа"
|
||||
},
|
||||
@@ -5951,7 +6124,7 @@
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 192]],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 382]],
|
||||
"translation": "Ваши доски были импортированы."
|
||||
},
|
||||
"LqWW5F": {
|
||||
@@ -5968,6 +6141,27 @@
|
||||
"origin": [["src/views/card/components/AttachmentUpload.tsx", 46]],
|
||||
"translation": "Ваш файл был успешно загружен."
|
||||
},
|
||||
"HcT8J4": {
|
||||
"message": "Your GitHub account has been connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 100]],
|
||||
"translation": "Ваш аккаунт GitHub был подключён."
|
||||
},
|
||||
"AdxYds": {
|
||||
"message": "Your GitHub account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 123]],
|
||||
"translation": "Ваш аккаунт GitHub был отключён."
|
||||
},
|
||||
"PELbXB": {
|
||||
"message": "Your GitHub account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 220]],
|
||||
"translation": "Ваш аккаунт GitHub подключён."
|
||||
},
|
||||
"Ozt2vv": {
|
||||
"message": "Your password has been changed.",
|
||||
"placeholders": {},
|
||||
@@ -5984,18 +6178,25 @@
|
||||
"origin": [["src/views/settings/components/Avatar.tsx", 190]],
|
||||
"translation": "Ваше изображение профиля было обновлено."
|
||||
},
|
||||
"+jbXzb": {
|
||||
"message": "Your projects have been imported.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/boards/components/ImportBoardsForm.tsx", 230]],
|
||||
"translation": "Ваши проекты были импортированы."
|
||||
},
|
||||
"CJWDTP": {
|
||||
"message": "Your Trello account has been disconnected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 54]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 80]],
|
||||
"translation": "Ваш аккаунт Trello был отключён."
|
||||
},
|
||||
"WRsbHO": {
|
||||
"message": "Your Trello account is connected.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 102]],
|
||||
"origin": [["src/views/settings/IntegrationsSettings.tsx", 171]],
|
||||
"translation": "Ваш аккаунт Trello подключён."
|
||||
},
|
||||
"25fAUC": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2,48 +2,74 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
|
||||
import { env } from "~/env";
|
||||
|
||||
export default withRateLimit(
|
||||
{ points: 100, duration: 60 },
|
||||
async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(405).json({ message: "Method not allowed" });
|
||||
}
|
||||
|
||||
const { url, filename } = req.query;
|
||||
|
||||
if (!url || typeof url !== "string") {
|
||||
return res.status(400).json({
|
||||
message: "url parameter is required",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const downloadFilename = typeof filename === "string"
|
||||
? encodeURIComponent(filename)
|
||||
: "attachment";
|
||||
|
||||
const upstream = await fetch(url);
|
||||
|
||||
if (!upstream.ok) {
|
||||
return res.status(upstream.status).json({
|
||||
message: "Failed to fetch attachment",
|
||||
});
|
||||
if (req.method !== "GET") {
|
||||
return res.status(405).json({ message: "Method not allowed" });
|
||||
}
|
||||
|
||||
const contentType =
|
||||
upstream.headers.get("Content-Type") ?? "application/octet-stream";
|
||||
const { url, filename } = req.query;
|
||||
|
||||
res.setHeader("Content-Type", contentType);
|
||||
res.setHeader(
|
||||
"Content-Disposition",
|
||||
`attachment; filename="${downloadFilename}"; filename*=UTF-8''${downloadFilename}`,
|
||||
);
|
||||
if (!url || typeof url !== "string") {
|
||||
return res.status(400).json({ message: "url parameter is required" });
|
||||
}
|
||||
|
||||
const buffer = await upstream.arrayBuffer();
|
||||
return res.send(Buffer.from(buffer));
|
||||
} catch (error) {
|
||||
console.error("Error downloading attachment:", error);
|
||||
return res.status(500).json({ message: "Failed to download attachment" });
|
||||
}
|
||||
const s3Endpoint = env.S3_ENDPOINT;
|
||||
|
||||
if (s3Endpoint) {
|
||||
let parsed: URL;
|
||||
try {
|
||||
parsed = new URL(url);
|
||||
} catch {
|
||||
return res.status(400).json({ message: "Invalid URL" });
|
||||
}
|
||||
|
||||
const hostname = parsed.hostname.toLowerCase();
|
||||
let allowedHost: string;
|
||||
try {
|
||||
allowedHost = new URL(s3Endpoint).hostname.toLowerCase();
|
||||
} catch {
|
||||
return res.status(500).json({ message: "Storage endpoint misconfigured" });
|
||||
}
|
||||
|
||||
if (hostname !== allowedHost && !hostname.endsWith(`.${allowedHost}`)) {
|
||||
return res.status(403).json({ message: "URL not allowed" });
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const downloadFilename =
|
||||
typeof filename === "string"
|
||||
? encodeURIComponent(filename)
|
||||
: "attachment";
|
||||
|
||||
const upstream = await fetch(url);
|
||||
|
||||
if (!upstream.ok) {
|
||||
return res
|
||||
.status(upstream.status)
|
||||
.json({ message: "Failed to fetch attachment" });
|
||||
}
|
||||
|
||||
const contentType =
|
||||
upstream.headers.get("Content-Type") ?? "application/octet-stream";
|
||||
|
||||
res.setHeader("Content-Type", contentType);
|
||||
res.setHeader(
|
||||
"Content-Disposition",
|
||||
`attachment; filename="${downloadFilename}"; filename*=UTF-8''${downloadFilename}`,
|
||||
);
|
||||
|
||||
const buffer = await upstream.arrayBuffer();
|
||||
return res.send(Buffer.from(buffer));
|
||||
} catch (error) {
|
||||
console.error("Error downloading attachment:", error);
|
||||
return res
|
||||
.status(500)
|
||||
.json({ message: "Failed to download attachment" });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -58,7 +58,7 @@ export default function LoginPage() {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!isSignUpDisabled && (
|
||||
{(!isSignUpDisabled || redirect?.startsWith("/invite/")) && (
|
||||
<p className="mt-4 text-sm text-light-1000 dark:text-dark-1000">
|
||||
<Trans>
|
||||
Don't have an account?{" "}
|
||||
|
||||
@@ -28,7 +28,9 @@ export default function SignUpPage() {
|
||||
setMagicLinkRecipient(recipient);
|
||||
};
|
||||
|
||||
if (isSignUpDisabled) {
|
||||
const isInviteFlow = redirect?.startsWith("/invite/");
|
||||
|
||||
if (isSignUpDisabled && !isInviteFlow) {
|
||||
return (
|
||||
<>
|
||||
<PageHead title={t`Sign up | kan.bn`} />
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
HiOutlineStar,
|
||||
HiStar,
|
||||
} from "react-icons/hi2";
|
||||
|
||||
import { IoArchiveOutline } from "react-icons/io5";
|
||||
import Dropdown from "~/components/Dropdown";
|
||||
import { usePermissions } from "~/hooks/usePermissions";
|
||||
import { useModal } from "~/providers/modal";
|
||||
@@ -17,6 +17,7 @@ import { api } from "~/utils/api";
|
||||
export default function BoardDropdown({
|
||||
isTemplate,
|
||||
isLoading,
|
||||
isArchived,
|
||||
boardPublicId,
|
||||
isFavorite,
|
||||
boardName,
|
||||
@@ -24,28 +25,29 @@ export default function BoardDropdown({
|
||||
isTemplate: boolean;
|
||||
isLoading: boolean;
|
||||
boardPublicId: string;
|
||||
isArchived?: boolean;
|
||||
isFavorite?: boolean;
|
||||
boardName?: string;
|
||||
}) {
|
||||
const { openModal } = useModal();
|
||||
const { canEditBoard, canDeleteBoard, canCreateBoard } = usePermissions();
|
||||
const { showPopup } = usePopup();
|
||||
const { canEditBoard, canDeleteBoard, canCreateBoard, canArchiveBoard } =
|
||||
usePermissions();
|
||||
const utils = api.useUtils();
|
||||
|
||||
const handleToggleFavorite = () => {
|
||||
updateBoard.mutate({
|
||||
boardPublicId,
|
||||
favorite: !isFavorite,
|
||||
});
|
||||
};
|
||||
|
||||
const updateBoard = api.board.update.useMutation({
|
||||
onSuccess: (data, variables) => {
|
||||
onSuccess: (_data, variables) => {
|
||||
void utils.board.all.invalidate();
|
||||
void utils.board.byId.invalidate();
|
||||
|
||||
// Show popup notification
|
||||
if (variables.favorite !== undefined) {
|
||||
if (variables.isArchived !== undefined) {
|
||||
showPopup({
|
||||
header: variables.isArchived ? t`Board archived` : t`Board unarchived`,
|
||||
message: variables.isArchived
|
||||
? t`The board has been archived.`
|
||||
: t`The board has been unarchived.`,
|
||||
icon: "success",
|
||||
});
|
||||
} else if (variables.favorite !== undefined) {
|
||||
showPopup({
|
||||
header: variables.favorite
|
||||
? t`Added to favorites`
|
||||
@@ -65,27 +67,54 @@ export default function BoardDropdown({
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const handleToggleFavorite = () => {
|
||||
updateBoard.mutate({
|
||||
boardPublicId,
|
||||
favorite: !isFavorite,
|
||||
});
|
||||
};
|
||||
|
||||
const handleArchiveOrUnarchive = () => {
|
||||
updateBoard.mutate({
|
||||
boardPublicId,
|
||||
isArchived: !isArchived,
|
||||
});
|
||||
};
|
||||
|
||||
const isArchiveActionPending = updateBoard.isPending;
|
||||
|
||||
const items = [
|
||||
...(isTemplate && canCreateBoard
|
||||
? [
|
||||
{
|
||||
label: t`Make template`,
|
||||
action: () => openModal("CREATE_TEMPLATE"),
|
||||
icon: (
|
||||
<HiOutlineDocumentDuplicate className="h-[16px] w-[16px] text-dark-900" />
|
||||
),
|
||||
},
|
||||
]
|
||||
{
|
||||
label: t`Make template`,
|
||||
action: () => openModal("CREATE_TEMPLATE"),
|
||||
icon: (
|
||||
<HiOutlineDocumentDuplicate className="h-[16px] w-[16px] text-dark-900" />
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(!isTemplate && canEditBoard
|
||||
? [
|
||||
{
|
||||
label: t`Edit board URL`,
|
||||
action: () => openModal("UPDATE_BOARD_SLUG"),
|
||||
icon: <HiLink className="h-[16px] w-[16px] text-dark-900" />,
|
||||
},
|
||||
]
|
||||
{
|
||||
label: t`Edit board URL`,
|
||||
action: () => openModal("UPDATE_BOARD_SLUG"),
|
||||
icon: <HiLink className="h-[16px] w-[16px] text-dark-900" />,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(!isTemplate && canArchiveBoard
|
||||
? [
|
||||
{
|
||||
label: isArchived ? t`Unarchive board` : t`Archive board`,
|
||||
action: handleArchiveOrUnarchive,
|
||||
icon: (
|
||||
<IoArchiveOutline className="h-[16px] w-[16px] text-dark-900" />
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: isFavorite
|
||||
@@ -100,22 +129,26 @@ export default function BoardDropdown({
|
||||
},
|
||||
...(canDeleteBoard
|
||||
? [
|
||||
{
|
||||
label: isTemplate ? t`Delete template` : t`Delete board`,
|
||||
action: () => openModal("DELETE_BOARD"),
|
||||
icon: <HiOutlineTrash className="h-[16px] w-[16px] text-dark-900" />,
|
||||
},
|
||||
]
|
||||
{
|
||||
label: isTemplate ? t`Delete template` : t`Delete board`,
|
||||
action: () => openModal("DELETE_BOARD"),
|
||||
icon: (
|
||||
<HiOutlineTrash className="h-[16px] w-[16px] text-dark-900" />
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
|
||||
|
||||
if (items.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Dropdown disabled={isLoading} items={items}>
|
||||
<Dropdown
|
||||
disabled={isLoading || isArchiveActionPending}
|
||||
items={items}
|
||||
>
|
||||
<HiEllipsisHorizontal className="h-5 w-5 text-dark-900" />
|
||||
</Dropdown>
|
||||
);
|
||||
|
||||
@@ -494,7 +494,7 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
isTemplate={!!isTemplate}
|
||||
isLoading={!boardData}
|
||||
boardPublicId={boardId ?? ""}
|
||||
workspacePublicId={workspace.publicId}
|
||||
isArchived={boardData?.isArchived ?? false}
|
||||
isFavorite={boardData?.favorite}
|
||||
boardName={boardData?.name}
|
||||
/>
|
||||
@@ -598,13 +598,12 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
? `/templates/${boardId}/cards/${card.publicId}`
|
||||
: `/cards/${card.publicId}`
|
||||
}
|
||||
className={`mb-2 flex !cursor-pointer flex-col ${
|
||||
card.publicId.startsWith(
|
||||
"PLACEHOLDER",
|
||||
)
|
||||
? "pointer-events-none"
|
||||
: ""
|
||||
}`}
|
||||
className={`mb-2 flex !cursor-pointer flex-col ${card.publicId.startsWith(
|
||||
"PLACEHOLDER",
|
||||
)
|
||||
? "pointer-events-none"
|
||||
: ""
|
||||
}`}
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useModal } from "~/providers/modal";
|
||||
import { useWorkspace } from "~/providers/workspace";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
export function BoardsList({ isTemplate }: { isTemplate?: boolean }) {
|
||||
export function BoardsList({ isTemplate, archived = false }: { isTemplate?: boolean; archived?: boolean }) {
|
||||
const { workspace } = useWorkspace();
|
||||
const { openModal } = useModal();
|
||||
const { canCreateBoard } = usePermissions();
|
||||
@@ -26,6 +26,7 @@ export function BoardsList({ isTemplate }: { isTemplate?: boolean }) {
|
||||
{
|
||||
workspacePublicId: workspace.publicId,
|
||||
type: isTemplate ? "template" : "regular",
|
||||
archived: archived,
|
||||
},
|
||||
{ enabled: workspace.publicId ? true : false },
|
||||
);
|
||||
@@ -59,10 +60,10 @@ export function BoardsList({ isTemplate }: { isTemplate?: boolean }) {
|
||||
<div className="flex flex-col items-center">
|
||||
<HiOutlineRectangleStack className="h-10 w-10 text-light-800 dark:text-dark-800" />
|
||||
<p className="mb-2 mt-4 text-[14px] font-bold text-light-1000 dark:text-dark-950">
|
||||
{t`No ${isTemplate ? "templates" : "boards"}`}
|
||||
{archived ? t`No archived boards` : t`No ${isTemplate ? "templates" : "boards"}`}
|
||||
</p>
|
||||
<p className="text-[14px] text-light-900 dark:text-dark-900">
|
||||
{t`Get started by creating a new ${isTemplate ? "template" : "board"}`}
|
||||
{archived ? t`Boards you archive will appear here.` : t`Get started by creating a new ${isTemplate ? "template" : "board"}`}
|
||||
</p>
|
||||
</div>
|
||||
<Tooltip
|
||||
@@ -109,18 +110,18 @@ export function BoardsList({ isTemplate }: { isTemplate?: boolean }) {
|
||||
>
|
||||
<div className="group relative mr-5 flex h-[150px] w-full items-center justify-center rounded-md border border-dashed border-light-400 bg-light-50 shadow-sm hover:bg-light-200 dark:border-dark-600 dark:bg-dark-50 dark:hover:bg-dark-100">
|
||||
<PatternedBackground />
|
||||
<button
|
||||
onClick={(e) => handleToggleFavorite(e, board.publicId, board.favorite)}
|
||||
className={`absolute right-3 top-3 z-10 rounded p-1 transition-all hover:bg-light-300 dark:hover:bg-dark-200 ${board.favorite ? "" : "md:opacity-0 md:group-hover:opacity-100"
|
||||
}`}
|
||||
aria-label={board.favorite ? "Remove from favorites" : "Add to favorites"}
|
||||
>
|
||||
{board.favorite ? (
|
||||
<HiStar className="h-5 w-5 text-neutral-700 dark:text-dark-1000" />
|
||||
) : (
|
||||
<HiOutlineStar className="h-5 w-5 text-neutral-700 dark:text-dark-800" />
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => handleToggleFavorite(e, board.publicId, board.favorite)}
|
||||
className={`absolute right-3 top-3 z-10 rounded p-1 transition-all hover:bg-light-300 dark:hover:bg-dark-200 ${board.favorite ? "" : "md:opacity-0 md:group-hover:opacity-100"
|
||||
}`}
|
||||
aria-label={board.favorite ? "Remove from favorites" : "Add to favorites"}
|
||||
>
|
||||
{board.favorite ? (
|
||||
<HiStar className="h-5 w-5 text-neutral-700 dark:text-dark-1000" />
|
||||
) : (
|
||||
<HiOutlineStar className="h-5 w-5 text-neutral-700 dark:text-dark-800" />
|
||||
)}
|
||||
</button>
|
||||
<p className="px-4 text-[14px] font-bold text-neutral-700 dark:text-dark-1000">
|
||||
{board.name}
|
||||
</p>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { t } from "@lingui/core/macro";
|
||||
import { Plural, Trans } from "@lingui/react/macro";
|
||||
import { Fragment, useEffect, useState } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { FaTrello } from "react-icons/fa";
|
||||
import { FaGithub, FaTrello } from "react-icons/fa";
|
||||
import {
|
||||
HiChevronUpDown,
|
||||
HiMiniArrowTopRightOnSquare,
|
||||
@@ -27,12 +27,23 @@ const integrationProviders: Record<
|
||||
name: "Trello",
|
||||
icon: <FaTrello />,
|
||||
},
|
||||
github: {
|
||||
name: "GitHub",
|
||||
icon: <FaGithub />,
|
||||
},
|
||||
};
|
||||
|
||||
const SelectSource = ({ handleNextStep }: { handleNextStep: () => void }) => {
|
||||
const SelectSource = ({
|
||||
handleNextStep,
|
||||
}: {
|
||||
handleNextStep: (provider: string) => void;
|
||||
}) => {
|
||||
const { data: integrations, refetch: refetchIntegrations } =
|
||||
api.integration.providers.useQuery();
|
||||
const { control, handleSubmit } = useForm({
|
||||
const { data: githubStatus, refetch: refetchGithubStatus } =
|
||||
api.integration.getGitHubStatus.useQuery();
|
||||
|
||||
const { control, handleSubmit, watch } = useForm({
|
||||
defaultValues: {
|
||||
source: integrations?.[0]?.provider ?? "trello",
|
||||
},
|
||||
@@ -47,23 +58,36 @@ const SelectSource = ({ handleNextStep }: { handleNextStep: () => void }) => {
|
||||
},
|
||||
);
|
||||
|
||||
const hasIntegrations = integrations && integrations.length > 0;
|
||||
const availableIntegrations = [
|
||||
...(integrations ?? []),
|
||||
...(githubStatus?.connected ? [{ provider: "github" }] : []),
|
||||
];
|
||||
|
||||
const hasIntegrations = availableIntegrations.length > 0;
|
||||
|
||||
useEffect(() => {
|
||||
const handleFocus = () => {
|
||||
refetchIntegrations();
|
||||
void refetchIntegrations();
|
||||
void refetchGithubStatus();
|
||||
};
|
||||
window.addEventListener("focus", handleFocus);
|
||||
return () => {
|
||||
window.removeEventListener("focus", handleFocus);
|
||||
};
|
||||
}, [refetchIntegrations]);
|
||||
}, [refetchIntegrations, refetchGithubStatus]);
|
||||
|
||||
const onSubmit = () => {
|
||||
if (!hasIntegrations && trelloUrl) {
|
||||
window.open(trelloUrl.url, "trello_auth", "height=800,width=600");
|
||||
const selected = watch("source");
|
||||
if (
|
||||
selected === "trello" &&
|
||||
!integrations?.some((i) => i.provider === "trello")
|
||||
) {
|
||||
if (trelloUrl)
|
||||
window.open(trelloUrl.url, "trello_auth", "height=800,width=600");
|
||||
} else if (selected === "github" && !githubStatus?.connected) {
|
||||
window.open("/settings/integrations", "_blank");
|
||||
} else {
|
||||
handleNextStep();
|
||||
handleNextStep(selected);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -102,7 +126,7 @@ const SelectSource = ({ handleNextStep }: { handleNextStep: () => void }) => {
|
||||
>
|
||||
<Listbox.Options className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-light-50 py-1 text-base text-neutral-900 shadow-lg ring-1 ring-light-600 ring-opacity-5 focus:outline-none dark:bg-dark-300 dark:text-dark-1000 sm:text-sm">
|
||||
{hasIntegrations ? (
|
||||
integrations.map((integration, index) => (
|
||||
availableIntegrations.map((integration, index) => (
|
||||
<Listbox.Option
|
||||
key={`source_${index}`}
|
||||
className="relative cursor-default select-none px-1"
|
||||
@@ -123,18 +147,32 @@ const SelectSource = ({ handleNextStep }: { handleNextStep: () => void }) => {
|
||||
</Listbox.Option>
|
||||
))
|
||||
) : (
|
||||
<Listbox.Option
|
||||
key="trello_placeholder"
|
||||
className="font-sm relative cursor-default select-none px-1"
|
||||
value="trello"
|
||||
>
|
||||
<div className="flex items-center rounded-[5px] p-1 text-sm hover:bg-light-200 dark:hover:bg-dark-400">
|
||||
{integrationProviders.trello?.icon}
|
||||
<span className="ml-2 block truncate text-sm">
|
||||
{integrationProviders.trello?.name}
|
||||
</span>
|
||||
</div>
|
||||
</Listbox.Option>
|
||||
<>
|
||||
<Listbox.Option
|
||||
key="trello_placeholder"
|
||||
className="font-sm relative cursor-default select-none px-1"
|
||||
value="trello"
|
||||
>
|
||||
<div className="flex items-center rounded-[5px] p-1 text-sm hover:bg-light-200 dark:hover:bg-dark-400">
|
||||
{integrationProviders.trello?.icon}
|
||||
<span className="ml-2 block truncate text-sm">
|
||||
{integrationProviders.trello?.name}
|
||||
</span>
|
||||
</div>
|
||||
</Listbox.Option>
|
||||
<Listbox.Option
|
||||
key="github_placeholder"
|
||||
className="font-sm relative cursor-default select-none px-1"
|
||||
value="github"
|
||||
>
|
||||
<div className="flex items-center rounded-[5px] p-1 text-sm hover:bg-light-200 dark:hover:bg-dark-400">
|
||||
{integrationProviders.github?.icon}
|
||||
<span className="ml-2 block truncate text-sm">
|
||||
{integrationProviders.github?.name}
|
||||
</span>
|
||||
</div>
|
||||
</Listbox.Option>
|
||||
</>
|
||||
)}
|
||||
</Listbox.Options>
|
||||
</Transition>
|
||||
@@ -154,7 +192,159 @@ const SelectSource = ({ handleNextStep }: { handleNextStep: () => void }) => {
|
||||
!hasIntegrations ? <HiMiniArrowTopRightOnSquare /> : undefined
|
||||
}
|
||||
>
|
||||
{hasIntegrations ? t`Select source` : t`Connect Trello`}
|
||||
{hasIntegrations ? t`Select source` : t`Connect`}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
const ImportGithub: React.FC = () => {
|
||||
const utils = api.useUtils();
|
||||
const { closeModal } = useModal();
|
||||
const { workspace } = useWorkspace();
|
||||
const { showPopup } = usePopup();
|
||||
const [isSelectAllEnabled, setIsSelectAllEnabled] = useState(false);
|
||||
|
||||
const refetchBoards = () => utils.board.all.refetch();
|
||||
|
||||
const { data: projects, isLoading: projectsLoading } =
|
||||
api.import.github.getProjects.useQuery();
|
||||
|
||||
const {
|
||||
register: registerProjects,
|
||||
handleSubmit: handleSubmitProjects,
|
||||
setValue,
|
||||
watch,
|
||||
} = useForm({
|
||||
defaultValues: Object.fromEntries(
|
||||
projects?.map((project) => [project.id, true]) ?? [],
|
||||
),
|
||||
});
|
||||
|
||||
const importProjects = api.import.github.importProjects.useMutation({
|
||||
onSuccess: async () => {
|
||||
showPopup({
|
||||
header: t`Import complete`,
|
||||
message: t`Your projects have been imported.`,
|
||||
icon: "success",
|
||||
});
|
||||
try {
|
||||
await refetchBoards();
|
||||
closeModal();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
onError: () => {
|
||||
showPopup({
|
||||
header: t`Import failed`,
|
||||
message: t`Please try again later, or contact customer support.`,
|
||||
icon: "error",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const projectWatchers = projects?.map((project) => ({
|
||||
id: project.id,
|
||||
value: watch(project.id),
|
||||
}));
|
||||
|
||||
const projectCount =
|
||||
projectWatchers?.filter((w) => w.value === true).length ?? 0;
|
||||
|
||||
const onSubmitProjects = (values: Record<string, boolean>) => {
|
||||
const projectIds = Object.keys(values).filter(
|
||||
(key) => values[key] === true,
|
||||
);
|
||||
|
||||
importProjects.mutate({
|
||||
projectIds,
|
||||
workspacePublicId: workspace.publicId,
|
||||
});
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
if (projectsLoading) {
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center gap-1">
|
||||
<div className="h-[30px] w-full animate-pulse rounded-[5px] bg-light-200 dark:bg-dark-300" />
|
||||
<div className="h-[30px] w-full animate-pulse rounded-[5px] bg-light-200 dark:bg-dark-300" />
|
||||
<div className="h-[30px] w-full animate-pulse rounded-[5px] bg-light-200 dark:bg-dark-300" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!projects?.length) {
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<p className="text-sm text-neutral-500 dark:text-dark-900">
|
||||
{t`No projects found`}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return projects.map((project) => (
|
||||
<div key={project.id}>
|
||||
<label
|
||||
className="flex cursor-pointer items-center rounded-[5px] p-2 hover:bg-light-100 dark:hover:bg-dark-300"
|
||||
htmlFor={project.id}
|
||||
>
|
||||
<input
|
||||
id={project.id}
|
||||
type="checkbox"
|
||||
className="h-[14px] w-[14px] rounded bg-transparent ring-0 focus:outline-none focus:ring-0 focus:ring-offset-0"
|
||||
{...registerProjects(project.id)}
|
||||
/>
|
||||
<span className="ml-3 text-sm text-neutral-900 dark:text-dark-1000">
|
||||
{project.name}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
));
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmitProjects(onSubmitProjects)}>
|
||||
<div className="h-[105px] overflow-auto px-5">{renderContent()}</div>
|
||||
|
||||
<div className="mt-12 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<Toggle
|
||||
label={t`Select all`}
|
||||
isChecked={!!isSelectAllEnabled}
|
||||
onChange={() => {
|
||||
const newState = !isSelectAllEnabled;
|
||||
setIsSelectAllEnabled(newState);
|
||||
|
||||
for (const project of projects ?? []) {
|
||||
setValue(project.id, newState);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div className="space-x-2">
|
||||
<Button
|
||||
type="submit"
|
||||
isLoading={importProjects.isPending}
|
||||
disabled={
|
||||
importProjects.isPending ||
|
||||
projectsLoading ||
|
||||
!projects?.length ||
|
||||
!projects.some(
|
||||
(project) =>
|
||||
projectWatchers?.find((w) => w.id === project.id)?.value ===
|
||||
true,
|
||||
)
|
||||
}
|
||||
>
|
||||
<Trans>
|
||||
<Plural
|
||||
value={projectCount}
|
||||
one={`Import project (1)`}
|
||||
other={`Import projects (${projectCount})`}
|
||||
/>
|
||||
</Trans>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -213,7 +403,7 @@ const ImportTrello: React.FC = () => {
|
||||
value: watch(board.id),
|
||||
}));
|
||||
|
||||
const boardCount = boardWatchers?.filter((w) => w.value === true).length || 0;
|
||||
const boardCount = boardWatchers?.filter((w) => w.value === true).length ?? 0;
|
||||
|
||||
const onSubmitBoards = (values: Record<string, boolean>) => {
|
||||
const boardIds = Object.keys(values).filter((key) => values[key] === true);
|
||||
@@ -267,7 +457,7 @@ const ImportTrello: React.FC = () => {
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmitBoards(onSubmitBoards)}>
|
||||
<div className="h-[105px] overflow-scroll px-5">{renderContent()}</div>
|
||||
<div className="h-[105px] overflow-auto px-5">{renderContent()}</div>
|
||||
|
||||
<div className="mt-12 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<Toggle
|
||||
@@ -277,7 +467,7 @@ const ImportTrello: React.FC = () => {
|
||||
const newState = !isSelectAllEnabled;
|
||||
setIsSelectAllEnabled(newState);
|
||||
|
||||
for (const board of boards || []) {
|
||||
for (const board of boards ?? []) {
|
||||
setValue(board.id, newState);
|
||||
}
|
||||
}}
|
||||
@@ -313,6 +503,7 @@ const ImportTrello: React.FC = () => {
|
||||
export function ImportBoardsForm() {
|
||||
const { closeModal } = useModal();
|
||||
const [step, setStep] = useState(1);
|
||||
const [provider, setProvider] = useState<string | null>(null);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -339,8 +530,16 @@ export function ImportBoardsForm() {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{step === 1 && <SelectSource handleNextStep={() => setStep(step + 1)} />}
|
||||
{step === 2 && <ImportTrello />}
|
||||
{step === 1 && (
|
||||
<SelectSource
|
||||
handleNextStep={(p) => {
|
||||
setProvider(p);
|
||||
setStep(step + 1);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{step === 2 && provider === "trello" && <ImportTrello />}
|
||||
{step === 2 && provider === "github" && <ImportGithub />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import {
|
||||
Listbox,
|
||||
ListboxButton,
|
||||
ListboxOption,
|
||||
ListboxOptions,
|
||||
} from "@headlessui/react";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { HiArrowDownTray, HiOutlinePlusSmall } from "react-icons/hi2";
|
||||
import { HiArrowDownTray, HiChevronDown, HiOutlinePlusSmall } from "react-icons/hi2";
|
||||
import { useState } from "react";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import FeedbackModal from "~/components/FeedbackModal";
|
||||
@@ -15,9 +22,15 @@ import { BoardsList } from "./components/BoardsList";
|
||||
import { ImportBoardsForm } from "./components/ImportBoardsForm";
|
||||
import { NewBoardForm } from "./components/NewBoardForm";
|
||||
|
||||
const boardsTabs = [
|
||||
{ key: "boards" as const, label: t`Active` },
|
||||
{ key: "archived" as const, label: t`Archived` },
|
||||
];
|
||||
|
||||
export default function BoardsPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
const { openModal, modalContentType, isOpen } = useModal();
|
||||
const { workspace } = useWorkspace();
|
||||
const [activeTab, setActiveTab] = useState<"boards" | "archived">("boards");
|
||||
const { canCreateBoard } = usePermissions();
|
||||
|
||||
const { tooltipContent: createModalShortcutTooltipContent } =
|
||||
@@ -34,7 +47,7 @@ export default function BoardsPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
<PageHead
|
||||
title={t`${isTemplate ? "Templates" : "Boards"} | ${workspace.name ?? t`Workspace`}`}
|
||||
/>
|
||||
<div className="m-auto h-full max-w-[1100px] p-6 px-5 md:px-28 md:py-12">
|
||||
<div className="m-auto h-full max-w-[1100px] p-8 px-5 md:px-28 md:py-12">
|
||||
<div className="relative z-10 mb-8 flex w-full items-center justify-between">
|
||||
<h1 className="font-bold tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
|
||||
{t`${isTemplate ? "Templates" : "Boards"}`}
|
||||
@@ -115,9 +128,79 @@ export default function BoardsPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
</Modal>
|
||||
</>
|
||||
|
||||
<div className="flex h-full flex-row">
|
||||
<BoardsList isTemplate={!!isTemplate} />
|
||||
</div>
|
||||
{!isTemplate ? (
|
||||
<div className="flex h-full w-full flex-col">
|
||||
<div className="focus:outline-none">
|
||||
<div className="sm:hidden">
|
||||
<Listbox
|
||||
value={activeTab}
|
||||
onChange={(tab) => setActiveTab(tab)}
|
||||
>
|
||||
<div className="relative mb-4">
|
||||
<ListboxButton className="w-full appearance-none rounded-md border-0 bg-light-50 py-3 pl-3 pr-10 text-left text-sm font-semibold text-light-1000 shadow-sm ring-1 ring-inset ring-light-300 dark:bg-dark-50 dark:text-dark-1000 dark:ring-dark-300 dark:focus:ring-dark-500">
|
||||
{boardsTabs.find((tab) => tab.key === activeTab)?.label ??
|
||||
"Select a tab"}
|
||||
<HiChevronDown
|
||||
aria-hidden="true"
|
||||
className="pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-light-900 dark:text-dark-900"
|
||||
/>
|
||||
</ListboxButton>
|
||||
<ListboxOptions className="absolute z-10 mt-1 w-full rounded-md bg-light-50 py-1 text-sm shadow-lg ring-1 ring-inset ring-light-300 dark:bg-dark-50 dark:ring-dark-300">
|
||||
{boardsTabs.map((tab) => (
|
||||
<ListboxOption
|
||||
key={tab.key}
|
||||
value={tab.key}
|
||||
className={({ selected }) =>
|
||||
`relative cursor-pointer select-none py-2 pl-3 pr-9 ${selected
|
||||
? "font-bold text-light-1000 dark:text-dark-1000"
|
||||
: "font-normal text-light-1000 dark:text-dark-1000"
|
||||
}`
|
||||
}
|
||||
>
|
||||
{tab.label}
|
||||
</ListboxOption>
|
||||
))}
|
||||
</ListboxOptions>
|
||||
</div>
|
||||
</Listbox>
|
||||
</div>
|
||||
<div className="hidden sm:block">
|
||||
<div>
|
||||
<nav
|
||||
aria-label="Tabs"
|
||||
className="-mb-px flex space-x-8 focus:outline-none"
|
||||
>
|
||||
{boardsTabs.map((tab) => (
|
||||
<button
|
||||
key={tab.key}
|
||||
type="button"
|
||||
onClick={() => setActiveTab(tab.key)}
|
||||
className={`whitespace-nowrap px-1 py-0 mt-2 mb-8 text-sm font-semibold transition-colors focus:outline-none ${activeTab === tab.key
|
||||
? "border-light-1000 text-light-1000 dark:border-dark-1000 dark:text-dark-1000"
|
||||
: "border-transparent text-light-900 hover:border-light-950 hover:text-light-950 dark:text-dark-900 dark:hover:border-white/20 dark:hover:text-dark-950"
|
||||
}`}
|
||||
>
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex h-full flex-row focus:outline-none">
|
||||
{activeTab === "boards" && (
|
||||
<BoardsList isTemplate={false} archived={false} />
|
||||
)}
|
||||
{activeTab === "archived" && (
|
||||
<BoardsList isTemplate={false} archived={true} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex h-full flex-row">
|
||||
<BoardsList isTemplate={!!isTemplate} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -3,8 +3,8 @@ import { useRouter } from "next/router";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { IoChevronForwardSharp } from "react-icons/io5";
|
||||
import { HiXMark } from "react-icons/hi2";
|
||||
import { IoChevronForwardSharp } from "react-icons/io5";
|
||||
|
||||
import { authClient } from "@kan/auth/client";
|
||||
|
||||
@@ -302,7 +302,6 @@ export default function CardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
|
||||
if (!cardId) return <></>;
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHead
|
||||
@@ -345,7 +344,7 @@ export default function CardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
className="flex h-7 w-7 items-center justify-center rounded-[5px] text-light-900 hover:bg-light-200 dark:text-dark-900 dark:hover:bg-dark-200"
|
||||
aria-label={t`Close`}
|
||||
>
|
||||
<HiXMark className="h-5 w-5" />
|
||||
<HiXMark className="h-4 w-4" />
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -8,10 +8,10 @@ type FrequencyValue = "monthly" | "annually";
|
||||
interface PlanFeature {
|
||||
key: string;
|
||||
label: string;
|
||||
free: string | boolean | { text: string; highlight?: string };
|
||||
teams: string | boolean | { text: string; highlight?: string };
|
||||
pro: string | boolean | { text: string; highlight?: string };
|
||||
enterprise: string | boolean | { text: string; highlight?: string };
|
||||
free: string | boolean | { text: string; highlight?: boolean; highlightFirstWord?: boolean };
|
||||
teams: string | boolean | { text: string; highlight?: boolean; highlightFirstWord?: boolean };
|
||||
pro: string | boolean | { text: string; highlight?: boolean; highlightFirstWord?: boolean };
|
||||
enterprise: string | boolean | { text: string; highlight?: boolean; highlightFirstWord?: boolean };
|
||||
}
|
||||
|
||||
interface FeatureSection {
|
||||
@@ -71,34 +71,34 @@ const FeatureComparisonTable = ({
|
||||
{
|
||||
key: "boards",
|
||||
label: t`Boards`,
|
||||
free: { text: t`Unlimited boards`, highlight: "Unlimited" },
|
||||
teams: { text: t`Unlimited boards`, highlight: "Unlimited" },
|
||||
pro: { text: t`Unlimited boards`, highlight: "Unlimited" },
|
||||
enterprise: { text: t`Unlimited boards`, highlight: "Unlimited" },
|
||||
free: { text: t`Unlimited boards`, highlightFirstWord: true },
|
||||
teams: { text: t`Unlimited boards`, highlightFirstWord: true },
|
||||
pro: { text: t`Unlimited boards`, highlightFirstWord: true },
|
||||
enterprise: { text: t`Unlimited boards`, highlightFirstWord: true },
|
||||
},
|
||||
{
|
||||
key: "members",
|
||||
label: t`Members`,
|
||||
free: { text: t`1 user`, highlight: "1" },
|
||||
teams: { text: t`Per-seat pricing`, highlight: "Per-seat" },
|
||||
pro: { text: t`Unlimited members`, highlight: "Unlimited" },
|
||||
enterprise: { text: t`Unlimited members`, highlight: "Unlimited" },
|
||||
free: { text: t`1 user`, highlightFirstWord: true },
|
||||
teams: { text: t`Per-seat pricing`, highlightFirstWord: true },
|
||||
pro: { text: t`Unlimited members`, highlightFirstWord: true },
|
||||
enterprise: { text: t`Unlimited members`, highlightFirstWord: true },
|
||||
},
|
||||
{
|
||||
key: "file-uploads",
|
||||
label: t`File uploads`,
|
||||
free: { text: t`10mb file uploads`, highlight: "10mb" },
|
||||
teams: { text: t`Unlimited file uploads`, highlight: "Unlimited" },
|
||||
pro: { text: t`Unlimited file uploads`, highlight: "Unlimited" },
|
||||
enterprise: { text: t`Unlimited file uploads`, highlight: "Unlimited" },
|
||||
free: { text: t`10mb file uploads`, highlightFirstWord: true },
|
||||
teams: { text: t`Unlimited file uploads`, highlightFirstWord: true },
|
||||
pro: { text: t`Unlimited file uploads`, highlightFirstWord: true },
|
||||
enterprise: { text: t`Unlimited file uploads`, highlightFirstWord: true },
|
||||
},
|
||||
{
|
||||
key: "workspace-username",
|
||||
label: t`Workspace username`,
|
||||
free: { text: t`Default username`, highlight: "Default" },
|
||||
teams: { text: t`Default username`, highlight: "Default" },
|
||||
pro: { text: t`Custom username`, highlight: "Custom" },
|
||||
enterprise: { text: t`Custom username`, highlight: "Custom" },
|
||||
free: { text: t`Default username`, highlightFirstWord: true },
|
||||
teams: { text: t`Default username`, highlightFirstWord: true },
|
||||
pro: { text: t`Custom username`, highlightFirstWord: true },
|
||||
enterprise: { text: t`Custom username`, highlightFirstWord: true },
|
||||
},
|
||||
];
|
||||
|
||||
@@ -236,9 +236,9 @@ const FeatureComparisonTable = ({
|
||||
key: "rest-api",
|
||||
label: t`API`,
|
||||
free: { text: t`Limited API access` },
|
||||
teams: { text: t`Full API access` },
|
||||
pro: { text: t`Full API access` },
|
||||
enterprise: { text: t`Full API access` },
|
||||
teams: { text: t`Full API access`, highlight: true },
|
||||
pro: { text: t`Full API access`, highlight: true },
|
||||
enterprise: { text: t`Full API access`, highlight: true },
|
||||
},
|
||||
{
|
||||
key: "self-hostable",
|
||||
@@ -254,18 +254,18 @@ const FeatureComparisonTable = ({
|
||||
{
|
||||
key: "sso",
|
||||
label: t`SSO`,
|
||||
free: { text: t`Google SSO` },
|
||||
teams: { text: t`Google SSO` },
|
||||
pro: { text: t`Google SSO` },
|
||||
enterprise: { text: t`Google SSO + SAML` },
|
||||
free: { text: t`Google SSO`, highlight: true },
|
||||
teams: { text: t`Google SSO`, highlight: true },
|
||||
pro: { text: t`Google SSO`, highlight: true },
|
||||
enterprise: { text: t`Google SSO + SAML`, highlight: true },
|
||||
},
|
||||
{
|
||||
key: "admin-roles",
|
||||
label: t`Admin roles`,
|
||||
free: { text: t`Admin roles` },
|
||||
teams: { text: t`Admin roles` },
|
||||
pro: { text: t`Admin roles` },
|
||||
enterprise: { text: t`Advanced admin roles` },
|
||||
free: { text: t`Admin roles`, highlight: true },
|
||||
teams: { text: t`Admin roles`, highlight: true },
|
||||
pro: { text: t`Admin roles`, highlight: true },
|
||||
enterprise: { text: t`Advanced admin roles`, highlight: true },
|
||||
},
|
||||
];
|
||||
|
||||
@@ -334,59 +334,37 @@ const FeatureComparisonTable = ({
|
||||
{ id: "enterprise", name: t`Enterprise`, tierId: "tier-enterprise" },
|
||||
];
|
||||
|
||||
const isHighlightValue = (
|
||||
value: string | boolean | { text: string; highlight?: string },
|
||||
): value is { text: string; highlight?: string } => {
|
||||
return typeof value === "object" && value !== null && "text" in value;
|
||||
};
|
||||
|
||||
const shouldHighlight = (text: string): boolean => {
|
||||
const lowerText = text.toLowerCase();
|
||||
return ["unlimited", "multiple", "per-seat", "custom", "mentions", "full", "sso", "admin"].some(
|
||||
(keyword) => lowerText.includes(keyword),
|
||||
);
|
||||
};
|
||||
|
||||
const CellValue = ({
|
||||
value,
|
||||
label,
|
||||
}: {
|
||||
value: string | boolean | { text: string; highlight?: string };
|
||||
value: string | boolean | { text: string; highlight?: boolean; highlightFirstWord?: boolean };
|
||||
label: string;
|
||||
}) => {
|
||||
// Handle object with text and highlight
|
||||
if (isHighlightValue(value)) {
|
||||
const { text, highlight } = value;
|
||||
const isUnlimited = shouldHighlight(text);
|
||||
|
||||
let displayText;
|
||||
if (highlight) {
|
||||
const parts = text.split(new RegExp(`(${highlight})`, "gi"));
|
||||
displayText = (
|
||||
<>
|
||||
{parts.map((part, index) =>
|
||||
part.toLowerCase() === highlight.toLowerCase() ? (
|
||||
<span key={index} className="text-light-1000 dark:text-dark-1000">
|
||||
{part}
|
||||
</span>
|
||||
) : (
|
||||
<span key={index} className="text-light-950 dark:text-dark-800">
|
||||
{part}
|
||||
</span>
|
||||
),
|
||||
)}
|
||||
</>
|
||||
if (typeof value === "object" && value !== null) {
|
||||
const { text, highlight, highlightFirstWord } = value;
|
||||
|
||||
if (highlightFirstWord) {
|
||||
const spaceIndex = text.indexOf(" ");
|
||||
const firstWord = spaceIndex === -1 ? text : text.slice(0, spaceIndex);
|
||||
const rest = spaceIndex === -1 ? "" : text.slice(spaceIndex);
|
||||
return (
|
||||
<div className="flex items-center gap-2.5">
|
||||
<HiCheckCircle className="mt-0.5 h-4 w-4 shrink-0 text-light-1000 dark:text-dark-1000" />
|
||||
<span className="text-sm font-medium">
|
||||
<span className="text-light-1000 dark:text-dark-1000">{firstWord}</span>
|
||||
<span className="text-light-950 dark:text-dark-800">{rest}</span>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
displayText = text;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2.5">
|
||||
<HiCheckCircle
|
||||
className={twMerge(
|
||||
"mt-0.5 h-4 w-4 shrink-0",
|
||||
isUnlimited
|
||||
highlight
|
||||
? "text-light-1000 dark:text-dark-1000"
|
||||
: "text-light-400 dark:text-dark-600",
|
||||
)}
|
||||
@@ -394,44 +372,18 @@ const FeatureComparisonTable = ({
|
||||
<span
|
||||
className={twMerge(
|
||||
"text-sm font-medium",
|
||||
isUnlimited
|
||||
highlight
|
||||
? "text-light-1000 dark:text-dark-950"
|
||||
: "text-light-950 dark:text-dark-800",
|
||||
)}
|
||||
>
|
||||
{displayText}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof value === "string") {
|
||||
const isUnlimited = shouldHighlight(value);
|
||||
return (
|
||||
<div className="flex items-center gap-2.5">
|
||||
<HiCheckCircle
|
||||
className={twMerge(
|
||||
"mt-0.5 h-4 w-4 shrink-0",
|
||||
isUnlimited
|
||||
? "text-light-1000 dark:text-dark-1000"
|
||||
: "text-light-400 dark:text-dark-600",
|
||||
)}
|
||||
/>
|
||||
<span
|
||||
className={twMerge(
|
||||
"text-sm font-medium",
|
||||
isUnlimited
|
||||
? "text-light-1000 dark:text-dark-950"
|
||||
: "text-light-950 dark:text-dark-800",
|
||||
)}
|
||||
>
|
||||
{value}
|
||||
{text}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
// Boolean true - show checkmark icon
|
||||
return (
|
||||
<div className="flex items-center gap-2.5">
|
||||
<HiCheckCircle className="mt-0.5 h-4 w-4 shrink-0 text-light-1000 dark:text-dark-1000" />
|
||||
@@ -441,7 +393,7 @@ const FeatureComparisonTable = ({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// Boolean false - show cross icon
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2.5">
|
||||
<HiXCircle className="mt-0.5 h-4 w-4 shrink-0 text-light-400 dark:text-dark-600" />
|
||||
@@ -455,7 +407,7 @@ const FeatureComparisonTable = ({
|
||||
const getFeatureValue = (
|
||||
feature: PlanFeature,
|
||||
planId: string,
|
||||
): string | boolean | { text: string; highlight?: string } => {
|
||||
): string | boolean | { text: string; highlight?: boolean; highlightFirstWord?: boolean } => {
|
||||
switch (planId) {
|
||||
case "free":
|
||||
return feature.free;
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { HiMiniArrowTopRightOnSquare } from "react-icons/hi2";
|
||||
import { z } from "zod";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import FeedbackModal from "~/components/FeedbackModal";
|
||||
import Input from "~/components/Input";
|
||||
import Modal from "~/components/modal";
|
||||
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
||||
import { PageHead } from "~/components/PageHead";
|
||||
@@ -11,10 +15,28 @@ import { useModal } from "~/providers/modal";
|
||||
import { usePopup } from "~/providers/popup";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
const githubTokenSchema = z.object({
|
||||
token: z.string().min(1, { message: t`Token is required` }),
|
||||
});
|
||||
|
||||
type GitHubTokenFormValues = z.infer<typeof githubTokenSchema>;
|
||||
|
||||
export default function IntegrationsSettings() {
|
||||
const { modalContentType, isOpen } = useModal();
|
||||
const { showPopup } = usePopup();
|
||||
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { isDirty, errors },
|
||||
reset,
|
||||
} = useForm<GitHubTokenFormValues>({
|
||||
resolver: zodResolver(githubTokenSchema),
|
||||
defaultValues: {
|
||||
token: "",
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
data: integrations,
|
||||
refetch: refetchIntegrations,
|
||||
@@ -34,21 +56,25 @@ export default function IntegrationsSettings() {
|
||||
},
|
||||
);
|
||||
|
||||
const { data: githubStatus, refetch: refetchGithubStatus } =
|
||||
api.integration.getGitHubStatus.useQuery();
|
||||
|
||||
useEffect(() => {
|
||||
const handleFocus = () => {
|
||||
refetchIntegrations();
|
||||
void refetchIntegrations();
|
||||
void refetchGithubStatus();
|
||||
};
|
||||
window.addEventListener("focus", handleFocus);
|
||||
return () => {
|
||||
window.removeEventListener("focus", handleFocus);
|
||||
};
|
||||
}, [refetchIntegrations]);
|
||||
}, [refetchIntegrations, refetchGithubStatus]);
|
||||
|
||||
const { mutateAsync: disconnectTrello } =
|
||||
api.integration.disconnect.useMutation({
|
||||
onSuccess: () => {
|
||||
refetchIntegrations();
|
||||
refetchTrelloUrl();
|
||||
void refetchIntegrations();
|
||||
void refetchTrelloUrl();
|
||||
showPopup({
|
||||
header: t`Trello disconnected`,
|
||||
message: t`Your Trello account has been disconnected.`,
|
||||
@@ -64,6 +90,49 @@ export default function IntegrationsSettings() {
|
||||
},
|
||||
});
|
||||
|
||||
const { mutateAsync: saveGithubToken, isPending: isSavingGithubToken } =
|
||||
api.integration.saveGitHubToken.useMutation({
|
||||
onSuccess: () => {
|
||||
void refetchGithubStatus();
|
||||
reset();
|
||||
showPopup({
|
||||
header: t`GitHub connected`,
|
||||
message: t`Your GitHub account has been connected.`,
|
||||
icon: "success",
|
||||
});
|
||||
},
|
||||
onError: () => {
|
||||
showPopup({
|
||||
header: t`Error connecting GitHub`,
|
||||
message: t`An error occurred while connecting your GitHub account.`,
|
||||
icon: "error",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmitGithubToken = (data: GitHubTokenFormValues) => {
|
||||
void saveGithubToken({ token: data.token });
|
||||
};
|
||||
|
||||
const { mutateAsync: disconnectGithub } =
|
||||
api.integration.disconnectGitHub.useMutation({
|
||||
onSuccess: () => {
|
||||
void refetchGithubStatus();
|
||||
showPopup({
|
||||
header: t`GitHub disconnected`,
|
||||
message: t`Your GitHub account has been disconnected.`,
|
||||
icon: "success",
|
||||
});
|
||||
},
|
||||
onError: () => {
|
||||
showPopup({
|
||||
header: t`Error disconnecting GitHub`,
|
||||
message: t`An error occurred while disconnecting your GitHub account.`,
|
||||
icon: "error",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHead title={t`Settings | Integrations`} />
|
||||
@@ -112,6 +181,51 @@ export default function IntegrationsSettings() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mb-8 border-t border-light-300 dark:border-dark-300">
|
||||
<h2 className="mb-4 mt-8 text-[14px] font-bold text-neutral-900 dark:text-dark-1000">
|
||||
{t`GitHub`}
|
||||
</h2>
|
||||
{!githubStatus?.connected ? (
|
||||
<>
|
||||
<p className="mb-4 text-sm text-neutral-500 dark:text-dark-900">
|
||||
{t`Connect your GitHub account to import projects.`}
|
||||
</p>
|
||||
<form
|
||||
onSubmit={handleSubmit(onSubmitGithubToken)}
|
||||
className="flex gap-2"
|
||||
>
|
||||
<div className="mb-4 flex w-full max-w-[325px] items-center gap-2">
|
||||
<Input
|
||||
type="password"
|
||||
placeholder="Personal Access Token"
|
||||
{...register("token")}
|
||||
errorMessage={errors.token?.message}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="secondary"
|
||||
type="submit"
|
||||
disabled={!isDirty || isSavingGithubToken}
|
||||
isLoading={isSavingGithubToken}
|
||||
>
|
||||
{t`Connect GitHub`}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p className="mb-8 text-sm text-neutral-500 dark:text-dark-900">
|
||||
{t`Your GitHub account is connected.`}
|
||||
</p>
|
||||
<Button variant="secondary" onClick={() => disconnectGithub()}>
|
||||
{t`Disconnect GitHub`}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Global modals */}
|
||||
<Modal
|
||||
modalSize="md"
|
||||
|
||||
@@ -34,6 +34,7 @@ export const boardRouter = createTRPCRouter({
|
||||
z.object({
|
||||
workspacePublicId: z.string().min(12),
|
||||
type: z.enum(["regular", "template"]).optional(),
|
||||
archived: z.boolean().optional(),
|
||||
}),
|
||||
)
|
||||
.output(
|
||||
@@ -65,7 +66,10 @@ export const boardRouter = createTRPCRouter({
|
||||
ctx.db,
|
||||
workspace.id,
|
||||
userId,
|
||||
{ type: input.type }
|
||||
{
|
||||
type: input.type,
|
||||
archived: input.archived ?? false,
|
||||
}
|
||||
);
|
||||
|
||||
return result;
|
||||
@@ -153,24 +157,24 @@ export const boardRouter = createTRPCRouter({
|
||||
// Generate presigned URLs for workspace member avatars
|
||||
const workspaceWithAvatarUrls = result.workspace
|
||||
? {
|
||||
...result.workspace,
|
||||
members: await Promise.all(
|
||||
result.workspace.members.map(async (member) => {
|
||||
if (!member.user?.image) {
|
||||
return member;
|
||||
}
|
||||
...result.workspace,
|
||||
members: await Promise.all(
|
||||
result.workspace.members.map(async (member) => {
|
||||
if (!member.user?.image) {
|
||||
return member;
|
||||
}
|
||||
|
||||
const avatarUrl = await generateAvatarUrl(member.user.image);
|
||||
return {
|
||||
...member,
|
||||
user: {
|
||||
...member.user,
|
||||
image: avatarUrl,
|
||||
},
|
||||
};
|
||||
}),
|
||||
),
|
||||
}
|
||||
const avatarUrl = await generateAvatarUrl(member.user.image);
|
||||
return {
|
||||
...member,
|
||||
user: {
|
||||
...member.user,
|
||||
image: avatarUrl,
|
||||
},
|
||||
};
|
||||
}),
|
||||
),
|
||||
}
|
||||
: result.workspace;
|
||||
|
||||
// Generate presigned URLs for card member avatars
|
||||
@@ -461,7 +465,8 @@ export const boardRouter = createTRPCRouter({
|
||||
.regex(/^(?![-]+$)[a-zA-Z0-9-]+$/)
|
||||
.optional(),
|
||||
visibility: z.enum(["public", "private"]).optional(),
|
||||
favorite: z.boolean().optional()
|
||||
favorite: z.boolean().optional(),
|
||||
isArchived: z.boolean().optional(),
|
||||
}),
|
||||
)
|
||||
.output(z.object({ success: z.boolean() }).or(z.custom<Awaited<ReturnType<typeof boardRepo.update>>>()))
|
||||
@@ -503,7 +508,7 @@ export const boardRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
// Handle other updates (name, slug, visibility)
|
||||
const hasOtherUpdates = input.name || input.slug || input.visibility !== undefined;
|
||||
const hasOtherUpdates = input.name || input.slug || input.visibility !== undefined || input.isArchived !== undefined;
|
||||
|
||||
if (!hasOtherUpdates) {
|
||||
// Only favorite was updated, return success
|
||||
@@ -530,6 +535,7 @@ export const boardRouter = createTRPCRouter({
|
||||
slug: input.slug,
|
||||
boardPublicId: input.boardPublicId,
|
||||
visibility: input.visibility,
|
||||
isArchived: input.isArchived,
|
||||
});
|
||||
|
||||
if (!result)
|
||||
|
||||
@@ -13,6 +13,10 @@ import { mergeActivities } from "../utils/activities";
|
||||
import { sendMentionEmails } from "../utils/notifications";
|
||||
import { assertCanDelete, assertCanEdit, assertPermission } from "../utils/permissions";
|
||||
import { generateAttachmentUrl, generateAvatarUrl } from "@kan/shared/utils";
|
||||
import {
|
||||
createCardWebhookPayload,
|
||||
sendWebhooksForWorkspace,
|
||||
} from "../utils/webhook";
|
||||
|
||||
export const cardRouter = createTRPCRouter({
|
||||
create: protectedProcedure
|
||||
@@ -165,6 +169,32 @@ export const cardRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
// Fire webhooks (non-blocking)
|
||||
sendWebhooksForWorkspace(
|
||||
ctx.db,
|
||||
list.workspaceId,
|
||||
createCardWebhookPayload(
|
||||
"card.created",
|
||||
{
|
||||
id: String(newCard.id),
|
||||
title: input.title,
|
||||
description: input.description,
|
||||
dueDate: input.dueDate ?? null,
|
||||
listId: String(newCard.listId),
|
||||
},
|
||||
{
|
||||
boardId: list.boardPublicId,
|
||||
boardName: list.boardName,
|
||||
listName: list.name,
|
||||
user: ctx.user
|
||||
? { id: ctx.user.id, name: ctx.user.name }
|
||||
: undefined,
|
||||
},
|
||||
),
|
||||
).catch((error) => {
|
||||
console.error("Webhook delivery failed:", error);
|
||||
});
|
||||
|
||||
return newCard;
|
||||
}),
|
||||
addComment: protectedProcedure
|
||||
@@ -1007,6 +1037,59 @@ export const cardRouter = createTRPCRouter({
|
||||
await cardActivityRepo.bulkCreate(ctx.db, activities);
|
||||
}
|
||||
|
||||
// Build changes object for webhook
|
||||
const webhookChanges: Record<string, { from: unknown; to: unknown }> = {};
|
||||
if (input.title && existingCard.title !== input.title) {
|
||||
webhookChanges.title = { from: existingCard.title, to: input.title };
|
||||
}
|
||||
if (input.description && existingCard.description !== input.description) {
|
||||
webhookChanges.description = {
|
||||
from: existingCard.description,
|
||||
to: input.description,
|
||||
};
|
||||
}
|
||||
if (
|
||||
input.dueDate !== undefined &&
|
||||
previousDueDate?.getTime() !== input.dueDate?.getTime()
|
||||
) {
|
||||
webhookChanges.dueDate = { from: previousDueDate, to: input.dueDate };
|
||||
}
|
||||
if (newListId && existingCard.listId !== newListId) {
|
||||
webhookChanges.listId = { from: existingCard.listId, to: newListId };
|
||||
}
|
||||
|
||||
// Fire webhooks (non-blocking)
|
||||
sendWebhooksForWorkspace(
|
||||
ctx.db,
|
||||
card.workspaceId,
|
||||
createCardWebhookPayload(
|
||||
newListId && existingCard.listId !== newListId
|
||||
? "card.moved"
|
||||
: "card.updated",
|
||||
{
|
||||
id: String(result.id),
|
||||
title: result.title,
|
||||
description: result.description,
|
||||
dueDate: result.dueDate,
|
||||
listId: String(newListId ?? existingCard.listId),
|
||||
},
|
||||
{
|
||||
boardId: card.boardPublicId,
|
||||
boardName: card.boardName,
|
||||
listName: card.listName,
|
||||
user: ctx.user
|
||||
? { id: ctx.user.id, name: ctx.user.name }
|
||||
: undefined,
|
||||
changes:
|
||||
Object.keys(webhookChanges).length > 0
|
||||
? webhookChanges
|
||||
: undefined,
|
||||
},
|
||||
),
|
||||
).catch((error) => {
|
||||
console.error("Webhook delivery failed:", error);
|
||||
});
|
||||
|
||||
return result;
|
||||
}),
|
||||
delete: protectedProcedure
|
||||
@@ -1054,6 +1137,9 @@ export const cardRouter = createTRPCRouter({
|
||||
card.createdBy,
|
||||
);
|
||||
|
||||
// Fetch full card data before delete for webhook
|
||||
const fullCard = await cardRepo.getByPublicId(ctx.db, input.cardPublicId);
|
||||
|
||||
const deletedAt = new Date();
|
||||
|
||||
await cardRepo.softDelete(ctx.db, {
|
||||
@@ -1068,6 +1154,34 @@ export const cardRouter = createTRPCRouter({
|
||||
createdBy: userId,
|
||||
});
|
||||
|
||||
// Fire webhooks (non-blocking)
|
||||
if (fullCard) {
|
||||
sendWebhooksForWorkspace(
|
||||
ctx.db,
|
||||
card.workspaceId,
|
||||
createCardWebhookPayload(
|
||||
"card.deleted",
|
||||
{
|
||||
id: String(fullCard.id),
|
||||
title: fullCard.title,
|
||||
description: fullCard.description,
|
||||
dueDate: fullCard.dueDate,
|
||||
listId: String(fullCard.listId),
|
||||
},
|
||||
{
|
||||
boardId: card.boardPublicId,
|
||||
boardName: card.boardName,
|
||||
listName: card.listName,
|
||||
user: ctx.user
|
||||
? { id: ctx.user.id, name: ctx.user.name }
|
||||
: undefined,
|
||||
},
|
||||
),
|
||||
).catch((error) => {
|
||||
console.error("Webhook delivery failed:", error);
|
||||
});
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -81,6 +81,16 @@ export const checklistRouter = createTRPCRouter({
|
||||
return newChecklist;
|
||||
}),
|
||||
update: protectedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
summary: "Update a checklist",
|
||||
method: "PUT",
|
||||
path: "/checklists/{checklistPublicId}",
|
||||
description: "Updates a checklist by its public ID",
|
||||
tags: ["Cards"],
|
||||
protect: true,
|
||||
},
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
checklistPublicId: z.string().length(12),
|
||||
|
||||
@@ -11,10 +11,12 @@ import * as labelRepo from "@kan/db/repository/label.repo";
|
||||
import * as listRepo from "@kan/db/repository/list.repo";
|
||||
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
import { colours } from "@kan/shared/constants";
|
||||
import { generateUID } from "@kan/shared/utils";
|
||||
import { generateSlug, generateUID } from "@kan/shared/utils";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
||||
import { assertPermission } from "../utils/permissions";
|
||||
import { assertUserInWorkspace } from "../utils/auth";
|
||||
import { decryptToken } from "../utils/encryption";
|
||||
import { apiKeys, urls } from "./integration";
|
||||
|
||||
export interface TrelloBoard {
|
||||
@@ -50,6 +52,51 @@ interface TrelloCheckItem {
|
||||
pos: number;
|
||||
}
|
||||
|
||||
interface GitHubProjectsResponse {
|
||||
data: {
|
||||
viewer: {
|
||||
projectsV2: {
|
||||
nodes?: { id: string; title: string }[];
|
||||
};
|
||||
organizations: {
|
||||
nodes: {
|
||||
projectsV2: {
|
||||
nodes?: { id: string; title: string }[];
|
||||
};
|
||||
}[];
|
||||
};
|
||||
};
|
||||
};
|
||||
errors?: unknown[];
|
||||
}
|
||||
|
||||
interface GitHubGraphQLResponse {
|
||||
data?: {
|
||||
node?: GitHubProjectV2Node;
|
||||
};
|
||||
errors?: unknown[];
|
||||
}
|
||||
|
||||
interface GitHubProjectV2Node {
|
||||
title: string;
|
||||
field?: {
|
||||
options?: { id: string; name: string }[];
|
||||
};
|
||||
areaField?: {
|
||||
options?: { id: string; name: string; color: string }[];
|
||||
};
|
||||
items?: {
|
||||
nodes: {
|
||||
fieldValueByName?: { name: string };
|
||||
areaValue?: { name: string };
|
||||
content?: {
|
||||
title?: string;
|
||||
body?: string;
|
||||
};
|
||||
}[];
|
||||
};
|
||||
}
|
||||
|
||||
interface TrelloCard {
|
||||
id: string;
|
||||
name: string | null;
|
||||
@@ -464,4 +511,436 @@ export const importRouter = createTRPCRouter({
|
||||
return { boardsCreated };
|
||||
}),
|
||||
}),
|
||||
github: createTRPCRouter({
|
||||
getProjects: protectedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
summary: "Get projects from GitHub",
|
||||
method: "GET",
|
||||
path: "/integrations/github/projects",
|
||||
description: "Retrieves all projects from GitHub",
|
||||
tags: ["Integrations"],
|
||||
protect: true,
|
||||
},
|
||||
})
|
||||
.input(z.void())
|
||||
.output(z.array(z.object({ id: z.string(), name: z.string() })))
|
||||
.query(async ({ ctx }) => {
|
||||
const user = ctx.user;
|
||||
|
||||
if (!user)
|
||||
throw new TRPCError({
|
||||
message: "User not authenticated",
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const integration = await integrationsRepo.getProviderForUser(
|
||||
ctx.db,
|
||||
user.id,
|
||||
"github",
|
||||
);
|
||||
|
||||
if (!integration)
|
||||
throw new TRPCError({
|
||||
message: "GitHub token not found",
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const token = decryptToken(integration.accessToken);
|
||||
|
||||
// GraphQL query to fetch Projects V2 for the user and their organizations
|
||||
const query = `
|
||||
query {
|
||||
viewer {
|
||||
projectsV2(first: 20) {
|
||||
nodes {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
organizations(first: 10) {
|
||||
nodes {
|
||||
projectsV2(first: 10) {
|
||||
nodes {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const response = await fetch("https://api.github.com/graphql", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `token ${token}`,
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "Kan-App",
|
||||
},
|
||||
body: JSON.stringify({ query }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error(
|
||||
`GitHub API Error: ${response.status} ${response.statusText}`,
|
||||
);
|
||||
console.error(`GitHub API Response: ${errorText}`);
|
||||
|
||||
throw new TRPCError({
|
||||
message: `Failed to fetch GitHub projects: ${response.status} ${response.statusText}`,
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
});
|
||||
}
|
||||
|
||||
const result = (await response.json()) as GitHubProjectsResponse;
|
||||
|
||||
if (result.errors) {
|
||||
console.error("GitHub GraphQL Errors:", result.errors);
|
||||
throw new TRPCError({
|
||||
message: "Failed to fetch GitHub projects (GraphQL Error)",
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
});
|
||||
}
|
||||
|
||||
const userProjects = result.data.viewer.projectsV2.nodes ?? [];
|
||||
const orgProjects = result.data.viewer.organizations.nodes.flatMap(
|
||||
(org) => org.projectsV2.nodes ?? [],
|
||||
);
|
||||
|
||||
const allProjects = [...userProjects, ...orgProjects];
|
||||
|
||||
return allProjects.map((project) => ({
|
||||
id: project.id,
|
||||
name: project.title,
|
||||
}));
|
||||
}),
|
||||
|
||||
importProjects: protectedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
summary: "Import projects from GitHub",
|
||||
method: "POST",
|
||||
path: "/imports/github/projects",
|
||||
description: "Imports projects from GitHub",
|
||||
tags: ["Imports"],
|
||||
protect: true,
|
||||
},
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
projectIds: z.array(z.string()),
|
||||
workspacePublicId: z.string().min(12),
|
||||
}),
|
||||
)
|
||||
.output(z.object({ projectsImported: z.number() }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
if (!userId) throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
|
||||
const integration = await integrationsRepo.getProviderForUser(
|
||||
ctx.db,
|
||||
userId,
|
||||
"github",
|
||||
);
|
||||
|
||||
if (!integration)
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "GitHub token not found",
|
||||
});
|
||||
|
||||
const token = decryptToken(integration.accessToken);
|
||||
|
||||
const workspace = await workspaceRepo.getByPublicId(
|
||||
ctx.db,
|
||||
input.workspacePublicId,
|
||||
);
|
||||
if (!workspace)
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Workspace not found",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(ctx.db, userId, workspace.id);
|
||||
|
||||
const newImport = await importRepo.create(ctx.db, {
|
||||
source: "github",
|
||||
createdBy: userId,
|
||||
});
|
||||
|
||||
if (!newImport) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: "Failed to create import record",
|
||||
});
|
||||
}
|
||||
|
||||
const newImportId = newImport.id;
|
||||
let projectsImported = 0;
|
||||
|
||||
for (const projectId of input.projectIds) {
|
||||
// GraphQL query to fetch Project V2 details, status options, area options, and items
|
||||
const query = `
|
||||
query($id: ID!) {
|
||||
node(id: $id) {
|
||||
... on ProjectV2 {
|
||||
title
|
||||
field(name: "Status") {
|
||||
... on ProjectV2SingleSelectField {
|
||||
options {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
areaField: field(name: "Area") {
|
||||
... on ProjectV2SingleSelectField {
|
||||
options {
|
||||
id
|
||||
name
|
||||
color
|
||||
}
|
||||
}
|
||||
}
|
||||
items(first: 100) {
|
||||
nodes {
|
||||
fieldValueByName(name: "Status") {
|
||||
... on ProjectV2ItemFieldSingleSelectValue {
|
||||
name
|
||||
}
|
||||
}
|
||||
areaValue: fieldValueByName(name: "Area") {
|
||||
... on ProjectV2ItemFieldSingleSelectValue {
|
||||
name
|
||||
}
|
||||
}
|
||||
content {
|
||||
... on Issue {
|
||||
title
|
||||
body
|
||||
}
|
||||
... on PullRequest {
|
||||
title
|
||||
body
|
||||
}
|
||||
... on DraftIssue {
|
||||
title
|
||||
body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const response = await fetch("https://api.github.com/graphql", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `token ${token}`,
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "Kan-App",
|
||||
},
|
||||
body: JSON.stringify({ query, variables: { id: projectId } }),
|
||||
});
|
||||
|
||||
const result = (await response.json()) as GitHubGraphQLResponse;
|
||||
if (result.errors || !result.data?.node) continue;
|
||||
|
||||
const projectData = result.data.node;
|
||||
const statusOptions = projectData.field?.options ?? [];
|
||||
const areaOptions = projectData.areaField?.options ?? [];
|
||||
const items = projectData.items?.nodes ?? [];
|
||||
|
||||
const boardPublicId = generateUID();
|
||||
const board = await boardRepo.create(ctx.db, {
|
||||
publicId: boardPublicId,
|
||||
name: projectData.title,
|
||||
workspaceId: workspace.id,
|
||||
slug: generateSlug(projectData.title),
|
||||
createdBy: userId,
|
||||
importId: newImportId,
|
||||
});
|
||||
|
||||
if (!board) continue;
|
||||
|
||||
// Prepare Labels
|
||||
const labelsInsert = areaOptions.map((option) => {
|
||||
let colourCode = "#0d9488"; // Default Teal
|
||||
const ghColor = option.color;
|
||||
|
||||
// Map GitHub colors to Kan colors
|
||||
if (ghColor === "BLUE") colourCode = "#0284c7";
|
||||
else if (ghColor === "GREEN") colourCode = "#65a30d";
|
||||
else if (ghColor === "YELLOW") colourCode = "#ca8a04";
|
||||
else if (ghColor === "ORANGE") colourCode = "#ea580c";
|
||||
else if (ghColor === "RED") colourCode = "#dc2626";
|
||||
else if (ghColor === "PINK") colourCode = "#db2777";
|
||||
else if (ghColor === "PURPLE") colourCode = "#4f46e5";
|
||||
else if (ghColor === "GRAY") colourCode = "#0d9488";
|
||||
|
||||
return {
|
||||
publicId: generateUID(),
|
||||
name: option.name,
|
||||
colourCode,
|
||||
createdBy: userId,
|
||||
boardId: board.id,
|
||||
importId: newImportId,
|
||||
};
|
||||
});
|
||||
|
||||
const createdLabels = await labelRepo.bulkCreate(
|
||||
ctx.db,
|
||||
labelsInsert,
|
||||
);
|
||||
const labelMap = new Map<string, number>();
|
||||
|
||||
createdLabels.forEach((label, index) => {
|
||||
const originalName = areaOptions[index]?.name;
|
||||
if (originalName) {
|
||||
labelMap.set(originalName, label.id);
|
||||
}
|
||||
});
|
||||
|
||||
// Prepare Lists
|
||||
const listsInsert: {
|
||||
publicId: string;
|
||||
name: string;
|
||||
createdBy: string;
|
||||
boardId: number;
|
||||
index: number;
|
||||
importId: number;
|
||||
}[] = [];
|
||||
|
||||
if (statusOptions.length === 0) {
|
||||
listsInsert.push({
|
||||
publicId: generateUID(),
|
||||
name: "To Do",
|
||||
createdBy: userId,
|
||||
boardId: board.id,
|
||||
index: 0,
|
||||
importId: newImportId,
|
||||
});
|
||||
} else {
|
||||
statusOptions.forEach((option, index) => {
|
||||
listsInsert.push({
|
||||
publicId: generateUID(),
|
||||
name: option.name,
|
||||
createdBy: userId,
|
||||
boardId: board.id,
|
||||
index: index,
|
||||
importId: newImportId,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const createdLists = await listRepo.bulkCreate(ctx.db, listsInsert);
|
||||
const listIdMap = new Map<string, number>();
|
||||
createdLists.forEach((list, index) => {
|
||||
const originalName = listsInsert[index]?.name;
|
||||
if (originalName) {
|
||||
listIdMap.set(originalName, list.id);
|
||||
}
|
||||
});
|
||||
|
||||
// Prepare Cards
|
||||
const itemsToInsert: {
|
||||
item: NonNullable<
|
||||
NonNullable<
|
||||
NonNullable<GitHubProjectV2Node["items"]>["nodes"]
|
||||
>[number]
|
||||
>;
|
||||
listId: number;
|
||||
title: string;
|
||||
description: string;
|
||||
}[] = [];
|
||||
|
||||
for (const item of items) {
|
||||
const statusName = item.fieldValueByName?.name;
|
||||
const content = item.content ?? {};
|
||||
const title = content.title ?? "Untitled Card";
|
||||
const description = content.body ?? "";
|
||||
|
||||
let listId = statusName ? listIdMap.get(statusName) : undefined;
|
||||
|
||||
// Fallback to first list
|
||||
if (!listId && createdLists.length > 0) {
|
||||
listId = createdLists[0]?.id;
|
||||
}
|
||||
|
||||
if (listId) {
|
||||
itemsToInsert.push({
|
||||
item,
|
||||
listId,
|
||||
title,
|
||||
description,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const cardsInput = itemsToInsert.map((data, index) => ({
|
||||
publicId: generateUID(),
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
createdBy: userId,
|
||||
listId: data.listId,
|
||||
index: index,
|
||||
importId: newImportId,
|
||||
}));
|
||||
|
||||
const createdCards = await cardRepo.bulkCreate(ctx.db, cardsInput);
|
||||
|
||||
// Create Activities
|
||||
const activities = createdCards.map((card) => ({
|
||||
type: "card.created" as const,
|
||||
cardId: card.id,
|
||||
createdBy: userId,
|
||||
}));
|
||||
|
||||
if (activities.length > 0) {
|
||||
await cardActivityRepo.bulkCreate(ctx.db, activities);
|
||||
}
|
||||
|
||||
// Link Labels
|
||||
const cardLabelRelations: { cardId: number; labelId: number }[] = [];
|
||||
createdCards.forEach((card, index) => {
|
||||
const originalItem = itemsToInsert[index]?.item;
|
||||
const areaName = originalItem?.areaValue?.name;
|
||||
|
||||
if (areaName) {
|
||||
const labelId = labelMap.get(areaName);
|
||||
if (labelId) {
|
||||
cardLabelRelations.push({
|
||||
cardId: card.id,
|
||||
labelId: labelId,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (cardLabelRelations.length > 0) {
|
||||
await cardRepo.bulkCreateCardLabelRelationships(
|
||||
ctx.db,
|
||||
cardLabelRelations,
|
||||
);
|
||||
}
|
||||
|
||||
projectsImported++;
|
||||
}
|
||||
|
||||
if (projectsImported > 0 && newImportId) {
|
||||
await importRepo.update(
|
||||
ctx.db,
|
||||
{ status: "success" },
|
||||
{ importId: newImportId },
|
||||
);
|
||||
}
|
||||
|
||||
return { projectsImported };
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -14,7 +14,65 @@ export const apiKeys = {
|
||||
trello: process.env.TRELLO_APP_API_KEY,
|
||||
};
|
||||
|
||||
import { encryptToken } from "../utils/encryption";
|
||||
|
||||
export const integrationRouter = createTRPCRouter({
|
||||
saveGitHubToken: protectedProcedure
|
||||
.input(z.object({ token: z.string() }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const user = ctx.user;
|
||||
|
||||
if (!user)
|
||||
throw new TRPCError({
|
||||
message: "User not authenticated",
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const encryptedToken = encryptToken(input.token);
|
||||
|
||||
const expiresAt = new Date();
|
||||
expiresAt.setFullYear(expiresAt.getFullYear() + 1);
|
||||
|
||||
await integrationsRepo.createOrUpdateProvider(ctx.db, {
|
||||
provider: "github",
|
||||
userId: user.id,
|
||||
accessToken: encryptedToken,
|
||||
expiresAt,
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
}),
|
||||
|
||||
disconnectGitHub: protectedProcedure.mutation(async ({ ctx }) => {
|
||||
const user = ctx.user;
|
||||
|
||||
if (!user)
|
||||
throw new TRPCError({
|
||||
message: "User not authenticated",
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
await integrationsRepo.deleteProviderForUser(ctx.db, user.id, "github");
|
||||
return { success: true };
|
||||
}),
|
||||
|
||||
getGitHubStatus: protectedProcedure.query(async ({ ctx }) => {
|
||||
const user = ctx.user;
|
||||
|
||||
if (!user)
|
||||
throw new TRPCError({
|
||||
message: "User not authenticated",
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const connected = await integrationsRepo.isProviderAvailableForUser(
|
||||
ctx.db,
|
||||
user.id,
|
||||
"github",
|
||||
);
|
||||
return { connected };
|
||||
}),
|
||||
|
||||
providers: protectedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
@@ -67,7 +125,7 @@ export const integrationRouter = createTRPCRouter({
|
||||
protect: true,
|
||||
},
|
||||
})
|
||||
.input(z.object({ provider: z.enum(["trello"]) }))
|
||||
.input(z.object({ provider: z.enum(["trello", "github"]) }))
|
||||
.output(z.object({}))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const user = ctx.user;
|
||||
|
||||
@@ -210,11 +210,12 @@ export const memberRouter = createTRPCRouter({
|
||||
input.memberPublicId,
|
||||
);
|
||||
|
||||
if (!member)
|
||||
if (!member || member.workspaceId !== workspace.id) {
|
||||
throw new TRPCError({
|
||||
message: `Member with public ID ${input.memberPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
}
|
||||
|
||||
const deletedMember = await memberRepo.softDelete(ctx.db, {
|
||||
memberId: member.id,
|
||||
@@ -720,7 +721,7 @@ export const memberRouter = createTRPCRouter({
|
||||
input.memberPublicId,
|
||||
);
|
||||
|
||||
if (!member) {
|
||||
if (!member || member.workspaceId !== workspace.id) {
|
||||
throw new TRPCError({
|
||||
message: "Member not found",
|
||||
code: "NOT_FOUND",
|
||||
|
||||
@@ -133,7 +133,7 @@ export const permissionRouter = createTRPCRouter({
|
||||
input.memberPublicId,
|
||||
);
|
||||
|
||||
if (!member) {
|
||||
if (!member || member.workspaceId !== workspace.id) {
|
||||
throw new TRPCError({
|
||||
message: "Member not found",
|
||||
code: "NOT_FOUND",
|
||||
@@ -209,7 +209,7 @@ export const permissionRouter = createTRPCRouter({
|
||||
input.memberPublicId,
|
||||
);
|
||||
|
||||
if (!member) {
|
||||
if (!member || member.workspaceId !== workspace.id) {
|
||||
throw new TRPCError({
|
||||
message: "Member not found",
|
||||
code: "NOT_FOUND",
|
||||
@@ -274,7 +274,7 @@ export const permissionRouter = createTRPCRouter({
|
||||
input.memberPublicId,
|
||||
);
|
||||
|
||||
if (!member) {
|
||||
if (!member || member.workspaceId !== workspace.id) {
|
||||
throw new TRPCError({
|
||||
message: "Member not found",
|
||||
code: "NOT_FOUND",
|
||||
@@ -339,7 +339,7 @@ export const permissionRouter = createTRPCRouter({
|
||||
input.memberPublicId,
|
||||
);
|
||||
|
||||
if (!member) {
|
||||
if (!member || member.workspaceId !== workspace.id) {
|
||||
throw new TRPCError({
|
||||
message: "Member not found",
|
||||
code: "NOT_FOUND",
|
||||
|
||||
53
packages/api/src/utils/encryption.ts
Normal file
53
packages/api/src/utils/encryption.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import crypto from "crypto";
|
||||
|
||||
const ALGORITHM = "aes-256-gcm";
|
||||
const SECRET_KEY = process.env.BETTER_AUTH_SECRET;
|
||||
|
||||
if (!SECRET_KEY) {
|
||||
throw new Error("Encryption key is missing. Set BETTER_AUTH_SECRET.");
|
||||
}
|
||||
|
||||
// Ensure the key is exactly 32 bytes
|
||||
const key = crypto.createHash("sha256").update(String(SECRET_KEY)).digest();
|
||||
|
||||
export const encryptToken = (text: string) => {
|
||||
const iv = crypto.randomBytes(12); // 12 bytes is the recommended IV size for GCM
|
||||
const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
|
||||
|
||||
// buffer concat is faster/cleaner for raw binary manipulation
|
||||
const encrypted = Buffer.concat([
|
||||
cipher.update(text, "utf8"),
|
||||
cipher.final(),
|
||||
]);
|
||||
|
||||
const authTag = cipher.getAuthTag();
|
||||
|
||||
// Combine IV + AuthTag + EncryptedData into one buffer
|
||||
// This saves space compared to storing them as separate hex strings
|
||||
const combined = Buffer.concat([iv, authTag, encrypted]);
|
||||
|
||||
// Return as URL-safe Base64 (ideal for cookies)
|
||||
return combined.toString("base64url");
|
||||
};
|
||||
|
||||
export const decryptToken = (text: string) => {
|
||||
// Convert URL-safe Base64 back to a Buffer
|
||||
const combined = Buffer.from(text, "base64url");
|
||||
|
||||
// Extract the parts based on fixed lengths
|
||||
// IV is 12 bytes (standard for GCM)
|
||||
// AuthTag is 16 bytes (standard for GCM)
|
||||
const iv = combined.subarray(0, 12);
|
||||
const authTag = combined.subarray(12, 28);
|
||||
const encryptedText = combined.subarray(28);
|
||||
|
||||
const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
|
||||
decipher.setAuthTag(authTag);
|
||||
|
||||
// If the cookie was tampered with, this will throw an error
|
||||
const decrypted = Buffer.concat([
|
||||
decipher.update(encryptedText),
|
||||
decipher.final(),
|
||||
]);
|
||||
return decrypted.toString("utf8");
|
||||
};
|
||||
528
packages/api/src/utils/webhook.test.ts
Normal file
528
packages/api/src/utils/webhook.test.ts
Normal file
@@ -0,0 +1,528 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
|
||||
vi.mock("@kan/db/repository/webhook.repo", () => ({
|
||||
getActiveByWorkspaceId: vi.fn(),
|
||||
}));
|
||||
|
||||
import * as webhookRepo from "@kan/db/repository/webhook.repo";
|
||||
import {
|
||||
sendWebhookToUrl,
|
||||
sendWebhooksForWorkspace,
|
||||
createCardWebhookPayload,
|
||||
webhookUrlSchema,
|
||||
type WebhookPayload,
|
||||
} from "./webhook";
|
||||
|
||||
const mockGetActiveByWorkspaceId = webhookRepo.getActiveByWorkspaceId as ReturnType<typeof vi.fn>;
|
||||
|
||||
describe("webhook utilities", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2024-01-15T12:00:00.000Z"));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
describe("createCardWebhookPayload", () => {
|
||||
it("creates a payload with required card fields", () => {
|
||||
const payload = createCardWebhookPayload(
|
||||
"card.created",
|
||||
{
|
||||
id: "card-123",
|
||||
title: "Test Card",
|
||||
listId: "list-456",
|
||||
},
|
||||
{
|
||||
boardId: "board-789",
|
||||
},
|
||||
);
|
||||
|
||||
expect(payload.event).toBe("card.created");
|
||||
expect(payload.timestamp).toBe("2024-01-15T12:00:00.000Z");
|
||||
expect(payload.data.card).toEqual({
|
||||
id: "card-123",
|
||||
title: "Test Card",
|
||||
description: undefined,
|
||||
dueDate: null,
|
||||
listId: "list-456",
|
||||
boardId: "board-789",
|
||||
});
|
||||
});
|
||||
|
||||
it("includes optional card fields when provided", () => {
|
||||
const dueDate = new Date("2024-02-01T10:00:00.000Z");
|
||||
const payload = createCardWebhookPayload(
|
||||
"card.updated",
|
||||
{
|
||||
id: "card-123",
|
||||
title: "Test Card",
|
||||
description: "A description",
|
||||
dueDate,
|
||||
listId: "list-456",
|
||||
},
|
||||
{
|
||||
boardId: "board-789",
|
||||
},
|
||||
);
|
||||
|
||||
expect(payload.data.card.description).toBe("A description");
|
||||
expect(payload.data.card.dueDate).toBe("2024-02-01T10:00:00.000Z");
|
||||
});
|
||||
|
||||
it("includes board context when provided", () => {
|
||||
const payload = createCardWebhookPayload(
|
||||
"card.created",
|
||||
{
|
||||
id: "card-123",
|
||||
title: "Test Card",
|
||||
listId: "list-456",
|
||||
},
|
||||
{
|
||||
boardId: "board-789",
|
||||
boardName: "My Board",
|
||||
},
|
||||
);
|
||||
|
||||
expect(payload.data.board).toEqual({
|
||||
id: "board-789",
|
||||
name: "My Board",
|
||||
});
|
||||
});
|
||||
|
||||
it("includes list context when provided", () => {
|
||||
const payload = createCardWebhookPayload(
|
||||
"card.created",
|
||||
{
|
||||
id: "card-123",
|
||||
title: "Test Card",
|
||||
listId: "list-456",
|
||||
},
|
||||
{
|
||||
boardId: "board-789",
|
||||
listName: "To Do",
|
||||
},
|
||||
);
|
||||
|
||||
expect(payload.data.list).toEqual({
|
||||
id: "list-456",
|
||||
name: "To Do",
|
||||
});
|
||||
});
|
||||
|
||||
it("includes user context when provided", () => {
|
||||
const payload = createCardWebhookPayload(
|
||||
"card.created",
|
||||
{
|
||||
id: "card-123",
|
||||
title: "Test Card",
|
||||
listId: "list-456",
|
||||
},
|
||||
{
|
||||
boardId: "board-789",
|
||||
user: {
|
||||
id: "user-111",
|
||||
name: "John Doe",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(payload.data.user).toEqual({
|
||||
id: "user-111",
|
||||
name: "John Doe",
|
||||
});
|
||||
});
|
||||
|
||||
it("includes changes for card.updated events", () => {
|
||||
const payload = createCardWebhookPayload(
|
||||
"card.updated",
|
||||
{
|
||||
id: "card-123",
|
||||
title: "Updated Title",
|
||||
listId: "list-456",
|
||||
},
|
||||
{
|
||||
boardId: "board-789",
|
||||
changes: {
|
||||
title: { from: "Old Title", to: "Updated Title" },
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(payload.data.changes).toEqual({
|
||||
title: { from: "Old Title", to: "Updated Title" },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("sendWebhookToUrl", () => {
|
||||
const originalFetch = global.fetch;
|
||||
|
||||
beforeEach(() => {
|
||||
global.fetch = vi.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = originalFetch;
|
||||
});
|
||||
|
||||
const mockPayload: WebhookPayload = {
|
||||
event: "card.created",
|
||||
timestamp: "2024-01-15T12:00:00.000Z",
|
||||
data: {
|
||||
card: {
|
||||
id: "card-123",
|
||||
title: "Test Card",
|
||||
listId: "list-456",
|
||||
boardId: "board-789",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
describe("SSRF protection", () => {
|
||||
it("blocks HTTP URLs", async () => {
|
||||
const result = await sendWebhookToUrl("http://example.com/webhook", undefined, mockPayload);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain("HTTPS");
|
||||
expect(global.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks localhost", async () => {
|
||||
const result = await sendWebhookToUrl("https://localhost/webhook", undefined, mockPayload);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain("Localhost");
|
||||
expect(global.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks 127.0.0.1", async () => {
|
||||
const result = await sendWebhookToUrl("https://127.0.0.1/webhook", undefined, mockPayload);
|
||||
expect(result.success).toBe(false);
|
||||
expect(global.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks cloud metadata endpoint", async () => {
|
||||
const result = await sendWebhookToUrl("https://169.254.169.254/latest/meta-data/", undefined, mockPayload);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain("metadata");
|
||||
expect(global.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks private 10.x.x.x IPs", async () => {
|
||||
const result = await sendWebhookToUrl("https://10.0.0.1/webhook", undefined, mockPayload);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain("Private");
|
||||
expect(global.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks private 192.168.x.x IPs", async () => {
|
||||
const result = await sendWebhookToUrl("https://192.168.1.1/webhook", undefined, mockPayload);
|
||||
expect(result.success).toBe(false);
|
||||
expect(global.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows valid HTTPS URLs", async () => {
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockResolvedValueOnce({ ok: true, status: 200 });
|
||||
const result = await sendWebhookToUrl("https://example.com/webhook", undefined, mockPayload);
|
||||
expect(result.success).toBe(true);
|
||||
expect(global.fetch).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it("sends POST request with correct headers", async () => {
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||||
ok: true,
|
||||
status: 200,
|
||||
});
|
||||
|
||||
await sendWebhookToUrl("https://example.com/webhook", undefined, mockPayload);
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
"https://example.com/webhook",
|
||||
expect.objectContaining({
|
||||
method: "POST",
|
||||
headers: expect.objectContaining({
|
||||
"Content-Type": "application/json",
|
||||
"X-Webhook-Event": "card.created",
|
||||
"X-Webhook-Timestamp": "2024-01-15T12:00:00.000Z",
|
||||
}),
|
||||
body: JSON.stringify(mockPayload),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("includes signature header when secret is provided", async () => {
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||||
ok: true,
|
||||
status: 200,
|
||||
});
|
||||
|
||||
await sendWebhookToUrl("https://example.com/webhook", "my-secret", mockPayload);
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
"https://example.com/webhook",
|
||||
expect.objectContaining({
|
||||
headers: expect.objectContaining({
|
||||
"X-Webhook-Signature": expect.stringMatching(/^[a-f0-9]{64}$/),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("returns success for 2xx responses", async () => {
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||||
ok: true,
|
||||
status: 200,
|
||||
});
|
||||
|
||||
const result = await sendWebhookToUrl(
|
||||
"https://example.com/webhook",
|
||||
undefined,
|
||||
mockPayload,
|
||||
);
|
||||
|
||||
expect(result).toEqual({ success: true, statusCode: 200 });
|
||||
});
|
||||
|
||||
it("returns failure for non-2xx responses", async () => {
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||||
ok: false,
|
||||
status: 500,
|
||||
statusText: "Internal Server Error",
|
||||
});
|
||||
|
||||
const result = await sendWebhookToUrl(
|
||||
"https://example.com/webhook",
|
||||
undefined,
|
||||
mockPayload,
|
||||
);
|
||||
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
statusCode: 500,
|
||||
error: "500 Internal Server Error",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns failure on network error", async () => {
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockRejectedValueOnce(
|
||||
new Error("Network error"),
|
||||
);
|
||||
|
||||
const result = await sendWebhookToUrl(
|
||||
"https://example.com/webhook",
|
||||
undefined,
|
||||
mockPayload,
|
||||
);
|
||||
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
error: "Network error",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns timeout error when request takes too long", async () => {
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockImplementationOnce(
|
||||
() =>
|
||||
new Promise((_, reject) => {
|
||||
setTimeout(() => {
|
||||
const error = new Error("Aborted");
|
||||
error.name = "AbortError";
|
||||
reject(error);
|
||||
}, 15000);
|
||||
}),
|
||||
);
|
||||
|
||||
const resultPromise = sendWebhookToUrl(
|
||||
"https://example.com/webhook",
|
||||
undefined,
|
||||
mockPayload,
|
||||
);
|
||||
|
||||
// Advance timers to trigger the abort
|
||||
vi.advanceTimersByTime(15000);
|
||||
|
||||
const result = await resultPromise;
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
error: "Request timed out",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("sendWebhooksForWorkspace", () => {
|
||||
const originalFetch = global.fetch;
|
||||
|
||||
beforeEach(() => {
|
||||
global.fetch = vi.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = originalFetch;
|
||||
});
|
||||
|
||||
const mockDb = {} as Parameters<typeof sendWebhooksForWorkspace>[0];
|
||||
|
||||
const mockPayload: WebhookPayload = {
|
||||
event: "card.created",
|
||||
timestamp: "2024-01-15T12:00:00.000Z",
|
||||
data: {
|
||||
card: {
|
||||
id: "card-123",
|
||||
title: "Test Card",
|
||||
listId: "list-456",
|
||||
boardId: "board-789",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
it("sends to all active webhooks subscribed to the event", async () => {
|
||||
mockGetActiveByWorkspaceId.mockResolvedValueOnce([
|
||||
{
|
||||
id: 1,
|
||||
publicId: "wh-1",
|
||||
url: "https://example.com/webhook1",
|
||||
secret: "secret1",
|
||||
events: ["card.created", "card.updated"],
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
publicId: "wh-2",
|
||||
url: "https://example.com/webhook2",
|
||||
secret: null,
|
||||
events: ["card.created"],
|
||||
active: true,
|
||||
},
|
||||
]);
|
||||
|
||||
(global.fetch as ReturnType<typeof vi.fn>).mockResolvedValue({
|
||||
ok: true,
|
||||
status: 200,
|
||||
});
|
||||
|
||||
await sendWebhooksForWorkspace(mockDb, 1, mockPayload);
|
||||
|
||||
// Event filtering now happens at DB level
|
||||
expect(mockGetActiveByWorkspaceId).toHaveBeenCalledWith(
|
||||
mockDb,
|
||||
1,
|
||||
"card.created",
|
||||
);
|
||||
expect(global.fetch).toHaveBeenCalledTimes(2);
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
"https://example.com/webhook1",
|
||||
expect.any(Object),
|
||||
);
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
"https://example.com/webhook2",
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
|
||||
it("does not send when no webhooks match the event (DB-level filtering)", async () => {
|
||||
// DB-level event filter returns empty array when no webhooks match
|
||||
mockGetActiveByWorkspaceId.mockResolvedValueOnce([]);
|
||||
|
||||
await sendWebhooksForWorkspace(mockDb, 1, mockPayload);
|
||||
|
||||
expect(mockGetActiveByWorkspaceId).toHaveBeenCalledWith(
|
||||
mockDb,
|
||||
1,
|
||||
"card.created",
|
||||
);
|
||||
expect(global.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("continues sending to other webhooks when one fails", async () => {
|
||||
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
|
||||
mockGetActiveByWorkspaceId.mockResolvedValueOnce([
|
||||
{
|
||||
id: 1,
|
||||
publicId: "wh-1",
|
||||
url: "https://example.com/webhook1",
|
||||
secret: null,
|
||||
events: ["card.created"],
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
publicId: "wh-2",
|
||||
url: "https://example.com/webhook2",
|
||||
secret: null,
|
||||
events: ["card.created"],
|
||||
active: true,
|
||||
},
|
||||
]);
|
||||
|
||||
(global.fetch as ReturnType<typeof vi.fn>)
|
||||
.mockResolvedValueOnce({ ok: false, status: 500, statusText: "Error" })
|
||||
.mockResolvedValueOnce({ ok: true, status: 200 });
|
||||
|
||||
await sendWebhooksForWorkspace(mockDb, 1, mockPayload);
|
||||
|
||||
expect(global.fetch).toHaveBeenCalledTimes(2);
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining("Webhook delivery failed"),
|
||||
);
|
||||
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("handles empty webhook list", async () => {
|
||||
mockGetActiveByWorkspaceId.mockResolvedValueOnce([]);
|
||||
|
||||
await sendWebhooksForWorkspace(mockDb, 1, mockPayload);
|
||||
|
||||
expect(global.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("catches and logs DB errors without throwing", async () => {
|
||||
const consoleSpy = vi
|
||||
.spyOn(console, "error")
|
||||
.mockImplementation(() => {});
|
||||
mockGetActiveByWorkspaceId.mockRejectedValueOnce(
|
||||
new Error("DB connection failed"),
|
||||
);
|
||||
|
||||
// Should not throw — the try/catch absorbs the error
|
||||
await expect(
|
||||
sendWebhooksForWorkspace(mockDb, 1, mockPayload),
|
||||
).resolves.toBeUndefined();
|
||||
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
"Failed to send webhooks for workspace:",
|
||||
expect.any(Error),
|
||||
);
|
||||
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("webhookUrlSchema", () => {
|
||||
it("accepts valid HTTPS URLs", () => {
|
||||
expect(webhookUrlSchema.safeParse("https://example.com/webhook").success).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects HTTP URLs", () => {
|
||||
const result = webhookUrlSchema.safeParse("http://example.com/webhook");
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects localhost", () => {
|
||||
const result = webhookUrlSchema.safeParse("https://localhost/webhook");
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects private IPs", () => {
|
||||
expect(webhookUrlSchema.safeParse("https://10.0.0.1/webhook").success).toBe(false);
|
||||
expect(webhookUrlSchema.safeParse("https://192.168.1.1/webhook").success).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects cloud metadata endpoints", () => {
|
||||
expect(webhookUrlSchema.safeParse("https://169.254.169.254/latest").success).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
258
packages/api/src/utils/webhook.ts
Normal file
258
packages/api/src/utils/webhook.ts
Normal file
@@ -0,0 +1,258 @@
|
||||
import crypto from "crypto";
|
||||
import { z } from "zod";
|
||||
|
||||
import type { dbClient } from "@kan/db/client";
|
||||
import type { WebhookEvent } from "@kan/db/schema";
|
||||
import * as webhookRepo from "@kan/db/repository/webhook.repo";
|
||||
|
||||
export type WebhookEventType = WebhookEvent;
|
||||
|
||||
export interface WebhookPayload {
|
||||
event: WebhookEventType;
|
||||
timestamp: string;
|
||||
data: {
|
||||
card: {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string | null;
|
||||
dueDate?: string | null; // ISO string after JSON serialization
|
||||
listId: string;
|
||||
boardId: string;
|
||||
};
|
||||
board?: {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
list?: {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
user?: {
|
||||
id: string;
|
||||
name: string | null;
|
||||
};
|
||||
changes?: Record<string, { from: unknown; to: unknown }>;
|
||||
};
|
||||
}
|
||||
|
||||
function generateSignature(payload: string, secret: string): string {
|
||||
return crypto.createHmac("sha256", secret).update(payload).digest("hex");
|
||||
}
|
||||
|
||||
/**
|
||||
* Zod schema for webhook URLs with SSRF mitigation.
|
||||
* Requires HTTPS and blocks private/internal IP ranges, localhost,
|
||||
* and cloud metadata endpoints.
|
||||
*/
|
||||
export const webhookUrlSchema = z
|
||||
.string()
|
||||
.url()
|
||||
.max(2048)
|
||||
.refine(
|
||||
(url) => {
|
||||
try {
|
||||
return new URL(url).protocol === "https:";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{ message: "Only HTTPS URLs are allowed" },
|
||||
)
|
||||
.refine(
|
||||
(url) => {
|
||||
try {
|
||||
const hostname = new URL(url).hostname.toLowerCase();
|
||||
return !(
|
||||
hostname === "localhost" ||
|
||||
hostname === "127.0.0.1" ||
|
||||
hostname === "::1" ||
|
||||
hostname === "0.0.0.0"
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{ message: "Localhost URLs are not allowed" },
|
||||
)
|
||||
.refine(
|
||||
(url) => {
|
||||
try {
|
||||
const hostname = new URL(url).hostname.toLowerCase();
|
||||
return !(
|
||||
hostname === "169.254.169.254" ||
|
||||
hostname === "metadata.google.internal"
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{ message: "Cloud metadata endpoints are not allowed" },
|
||||
)
|
||||
.refine(
|
||||
(url) => {
|
||||
try {
|
||||
const hostname = new URL(url).hostname.toLowerCase();
|
||||
const ipv4Match = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(hostname);
|
||||
if (ipv4Match) {
|
||||
const [, a, b] = ipv4Match.map(Number);
|
||||
if (
|
||||
a === 10 ||
|
||||
(a === 172 && b! >= 16 && b! <= 31) ||
|
||||
(a === 192 && b === 168)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{ message: "Private IP addresses are not allowed" },
|
||||
);
|
||||
|
||||
/**
|
||||
* Send a webhook payload to a specific URL.
|
||||
*
|
||||
* SSRF note: URL validation (HTTPS-only, no private IPs, no cloud metadata)
|
||||
* is enforced both here at delivery time and at webhook creation via
|
||||
* webhookUrlSchema. This function is only reachable by workspace admins.
|
||||
*/
|
||||
export async function sendWebhookToUrl(
|
||||
url: string,
|
||||
secret: string | undefined,
|
||||
payload: WebhookPayload,
|
||||
): Promise<{ success: boolean; statusCode?: number; error?: string }> {
|
||||
const result = webhookUrlSchema.safeParse(url);
|
||||
if (!result.success) {
|
||||
return { success: false, error: result.error.issues[0]?.message };
|
||||
}
|
||||
|
||||
const body = JSON.stringify(payload);
|
||||
const headers: Record<string, string> = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Webhook-Event": payload.event,
|
||||
"X-Webhook-Timestamp": payload.timestamp,
|
||||
};
|
||||
|
||||
if (secret) {
|
||||
headers["X-Webhook-Signature"] = generateSignature(body, secret);
|
||||
}
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body,
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
if (!response.ok) {
|
||||
return {
|
||||
success: false,
|
||||
statusCode: response.status,
|
||||
error: `${response.status} ${response.statusText}`,
|
||||
};
|
||||
}
|
||||
|
||||
return { success: true, statusCode: response.status };
|
||||
} catch (error) {
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
if (error instanceof Error && error.name === "AbortError") {
|
||||
return { success: false, error: "Request timed out" };
|
||||
}
|
||||
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : "Unknown error",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send webhook to all active webhooks for a workspace that are subscribed to the event.
|
||||
* Wrapped in try/catch so callers using fire-and-forget don't risk unhandled rejections.
|
||||
*/
|
||||
export async function sendWebhooksForWorkspace(
|
||||
db: dbClient,
|
||||
workspaceId: number,
|
||||
payload: WebhookPayload,
|
||||
): Promise<void> {
|
||||
try {
|
||||
// Get active webhooks for this workspace
|
||||
const webhooks = await webhookRepo.getActiveByWorkspaceId(db, workspaceId);
|
||||
|
||||
// Filter webhooks that are subscribed to this specific event
|
||||
const webhooksForEvent = webhooks.filter((webhook) =>
|
||||
webhook.events.includes(payload.event),
|
||||
);
|
||||
|
||||
// Send to all subscribed webhooks in parallel (fire and forget)
|
||||
const promises = webhooksForEvent.map((webhook) =>
|
||||
sendWebhookToUrl(webhook.url, webhook.secret ?? undefined, payload).then(
|
||||
(result) => {
|
||||
if (!result.success) {
|
||||
console.error(
|
||||
`Webhook delivery failed to ${webhook.url}: ${result.error}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// Wait for all to complete but don't block on failures
|
||||
await Promise.allSettled(promises);
|
||||
} catch (error) {
|
||||
console.error("Failed to send webhooks for workspace:", error);
|
||||
}
|
||||
}
|
||||
|
||||
export function createCardWebhookPayload(
|
||||
event: WebhookEventType,
|
||||
card: {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string | null;
|
||||
dueDate?: Date | null;
|
||||
listId: string;
|
||||
},
|
||||
context: {
|
||||
boardId: string;
|
||||
boardName?: string;
|
||||
listName?: string;
|
||||
user?: {
|
||||
id: string;
|
||||
name: string | null;
|
||||
};
|
||||
changes?: Record<string, { from: unknown; to: unknown }>;
|
||||
},
|
||||
): WebhookPayload {
|
||||
return {
|
||||
event,
|
||||
timestamp: new Date().toISOString(),
|
||||
data: {
|
||||
card: {
|
||||
id: card.id,
|
||||
title: card.title,
|
||||
description: card.description,
|
||||
dueDate: card.dueDate?.toISOString() ?? null,
|
||||
listId: card.listId,
|
||||
boardId: context.boardId,
|
||||
},
|
||||
board: context.boardName
|
||||
? { id: context.boardId, name: context.boardName }
|
||||
: undefined,
|
||||
list: context.listName
|
||||
? { id: card.listId, name: context.listName }
|
||||
: undefined,
|
||||
user: context.user,
|
||||
changes: context.changes,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
"dev": "tsc",
|
||||
"format": "prettier --check . --ignore-path ../../.gitignore",
|
||||
"lint": "eslint",
|
||||
"test": "vitest run",
|
||||
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -33,8 +33,10 @@ export const initAuth = (db: dbClient) => {
|
||||
},
|
||||
emailAndPassword: {
|
||||
enabled: env("NEXT_PUBLIC_ALLOW_CREDENTIALS")?.toLowerCase() === "true",
|
||||
disableSignUp:
|
||||
env("NEXT_PUBLIC_DISABLE_SIGN_UP")?.toLowerCase() === "true",
|
||||
// Sign-up restriction is handled by the user.create.before database
|
||||
// hook which checks for pending invitations, allowing invited users
|
||||
// to register even when public sign-up is disabled.
|
||||
disableSignUp: false,
|
||||
sendResetPassword: async (data) => {
|
||||
await sendEmail(data.user.email, "Reset Password", "RESET_PASSWORD", {
|
||||
resetPasswordUrl: data.url,
|
||||
|
||||
195
packages/auth/src/hooks.test.ts
Normal file
195
packages/auth/src/hooks.test.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
|
||||
vi.mock("next-runtime-env", () => ({
|
||||
env: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@kan/db/repository/member.repo", () => ({
|
||||
getByEmailAndStatus: vi.fn(),
|
||||
getByPublicId: vi.fn(),
|
||||
acceptInvite: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@kan/db/repository/user.repo", () => ({
|
||||
update: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@kan/email", () => ({
|
||||
notificationClient: null,
|
||||
}));
|
||||
|
||||
vi.mock("@kan/shared", () => ({
|
||||
createEmailUnsubscribeLink: vi.fn(),
|
||||
createS3Client: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@aws-sdk/client-s3", () => ({
|
||||
PutObjectCommand: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@novu/api/models/components", () => ({
|
||||
ChatOrPushProviderEnum: { Discord: "discord" },
|
||||
}));
|
||||
|
||||
import { env } from "next-runtime-env";
|
||||
import * as memberRepo from "@kan/db/repository/member.repo";
|
||||
import { createDatabaseHooks } from "./hooks";
|
||||
|
||||
const mockEnv = env as ReturnType<typeof vi.fn>;
|
||||
const mockGetByEmailAndStatus =
|
||||
memberRepo.getByEmailAndStatus as ReturnType<typeof vi.fn>;
|
||||
|
||||
const db = {} as Parameters<typeof createDatabaseHooks>[0];
|
||||
|
||||
const fakeUser = {
|
||||
id: "user-1",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
email: "test@example.com",
|
||||
emailVerified: false,
|
||||
name: "Test User",
|
||||
};
|
||||
|
||||
describe("createDatabaseHooks", () => {
|
||||
const hooks = createDatabaseHooks(db);
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("user.create.before", () => {
|
||||
it("allows sign-up when DISABLE_SIGN_UP is not set", async () => {
|
||||
mockEnv.mockReturnValue(undefined);
|
||||
|
||||
const result = await hooks.user.create.before(fakeUser, {});
|
||||
expect(result).toBe(true);
|
||||
expect(mockGetByEmailAndStatus).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows sign-up when DISABLE_SIGN_UP is false", async () => {
|
||||
mockEnv.mockImplementation((key: string) =>
|
||||
key === "NEXT_PUBLIC_DISABLE_SIGN_UP" ? "false" : undefined,
|
||||
);
|
||||
|
||||
const result = await hooks.user.create.before(fakeUser, {});
|
||||
expect(result).toBe(true);
|
||||
expect(mockGetByEmailAndStatus).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks sign-up when disabled and user has no pending invitation", async () => {
|
||||
mockEnv.mockImplementation((key: string) =>
|
||||
key === "NEXT_PUBLIC_DISABLE_SIGN_UP" ? "true" : undefined,
|
||||
);
|
||||
mockGetByEmailAndStatus.mockResolvedValue(undefined);
|
||||
|
||||
const result = await hooks.user.create.before(fakeUser, {});
|
||||
expect(result).toBe(false);
|
||||
expect(mockGetByEmailAndStatus).toHaveBeenCalledWith(
|
||||
db,
|
||||
"test@example.com",
|
||||
"invited",
|
||||
);
|
||||
});
|
||||
|
||||
it("allows sign-up when disabled but user has a pending invitation", async () => {
|
||||
mockEnv.mockImplementation((key: string) =>
|
||||
key === "NEXT_PUBLIC_DISABLE_SIGN_UP" ? "true" : undefined,
|
||||
);
|
||||
mockGetByEmailAndStatus.mockResolvedValue({
|
||||
id: "member-1",
|
||||
email: "test@example.com",
|
||||
status: "invited",
|
||||
});
|
||||
|
||||
const result = await hooks.user.create.before(fakeUser, {});
|
||||
expect(result).toBe(true);
|
||||
expect(mockGetByEmailAndStatus).toHaveBeenCalledWith(
|
||||
db,
|
||||
"test@example.com",
|
||||
"invited",
|
||||
);
|
||||
});
|
||||
|
||||
it("blocks sign-up when disabled and invitation exists but domain is not allowed", async () => {
|
||||
mockEnv.mockImplementation((key: string) =>
|
||||
key === "NEXT_PUBLIC_DISABLE_SIGN_UP" ? "true" : undefined,
|
||||
);
|
||||
process.env.BETTER_AUTH_ALLOWED_DOMAINS = "acme.com";
|
||||
mockGetByEmailAndStatus.mockResolvedValue({
|
||||
id: "member-1",
|
||||
email: "test@example.com",
|
||||
status: "invited",
|
||||
});
|
||||
|
||||
const result = await hooks.user.create.before(fakeUser, {});
|
||||
expect(result).toBe(false);
|
||||
|
||||
delete process.env.BETTER_AUTH_ALLOWED_DOMAINS;
|
||||
});
|
||||
|
||||
// The user.create.before hook fires for ALL sign-up paths including
|
||||
// OIDC/social — verify invite bypass works regardless of auth method.
|
||||
it("allows OIDC/social sign-up when disabled but user has a pending invitation", async () => {
|
||||
mockEnv.mockImplementation((key: string) =>
|
||||
key === "NEXT_PUBLIC_DISABLE_SIGN_UP" ? "true" : undefined,
|
||||
);
|
||||
const oidcUser = {
|
||||
...fakeUser,
|
||||
id: "user-oidc",
|
||||
email: "sso@corp.com",
|
||||
image: "https://provider.com/avatar.jpg",
|
||||
};
|
||||
mockGetByEmailAndStatus.mockResolvedValue({
|
||||
id: "member-2",
|
||||
email: "sso@corp.com",
|
||||
status: "invited",
|
||||
});
|
||||
|
||||
const result = await hooks.user.create.before(oidcUser, {});
|
||||
expect(result).toBe(true);
|
||||
expect(mockGetByEmailAndStatus).toHaveBeenCalledWith(
|
||||
db,
|
||||
"sso@corp.com",
|
||||
"invited",
|
||||
);
|
||||
});
|
||||
|
||||
it("blocks OIDC/social sign-up when disabled and user has no pending invitation", async () => {
|
||||
mockEnv.mockImplementation((key: string) =>
|
||||
key === "NEXT_PUBLIC_DISABLE_SIGN_UP" ? "true" : undefined,
|
||||
);
|
||||
const oidcUser = {
|
||||
...fakeUser,
|
||||
id: "user-oidc",
|
||||
email: "random@external.com",
|
||||
image: "https://provider.com/avatar.jpg",
|
||||
};
|
||||
mockGetByEmailAndStatus.mockResolvedValue(undefined);
|
||||
|
||||
const result = await hooks.user.create.before(oidcUser, {});
|
||||
expect(result).toBe(false);
|
||||
expect(mockGetByEmailAndStatus).toHaveBeenCalledWith(
|
||||
db,
|
||||
"random@external.com",
|
||||
"invited",
|
||||
);
|
||||
});
|
||||
|
||||
it("allows sign-up when disabled, invitation exists, and domain is allowed", async () => {
|
||||
mockEnv.mockImplementation((key: string) =>
|
||||
key === "NEXT_PUBLIC_DISABLE_SIGN_UP" ? "true" : undefined,
|
||||
);
|
||||
process.env.BETTER_AUTH_ALLOWED_DOMAINS = "example.com";
|
||||
mockGetByEmailAndStatus.mockResolvedValue({
|
||||
id: "member-1",
|
||||
email: "test@example.com",
|
||||
status: "invited",
|
||||
});
|
||||
|
||||
const result = await hooks.user.create.before(fakeUser, {});
|
||||
expect(result).toBe(true);
|
||||
|
||||
delete process.env.BETTER_AUTH_ALLOWED_DOMAINS;
|
||||
});
|
||||
});
|
||||
});
|
||||
14
packages/auth/vitest.config.ts
Normal file
14
packages/auth/vitest.config.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { resolve } from "path";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
root: __dirname,
|
||||
include: ["src/**/*.test.ts"],
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"@kan/db": resolve(__dirname, "../db/src"),
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TYPE "public"."source" ADD VALUE 'github';--> statement-breakpoint
|
||||
ALTER TABLE "integration" ALTER COLUMN "accessToken" SET DATA TYPE text;--> statement-breakpoint
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE "board" ADD COLUMN "isArchived" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
CREATE INDEX IF NOT EXISTS "board_is_archived_idx" ON "board" USING btree ("isArchived");
|
||||
2983
packages/db/migrations/meta/20260224105235_snapshot.json
Normal file
2983
packages/db/migrations/meta/20260224105235_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
3709
packages/db/migrations/meta/20260225195947_snapshot.json
Normal file
3709
packages/db/migrations/meta/20260225195947_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -197,6 +197,20 @@
|
||||
"when": 1771192000000,
|
||||
"tag": "20260129210000_AddWorkspaceWebhooks",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 28,
|
||||
"version": "7",
|
||||
"when": 1772049587901,
|
||||
"tag": "20260225195947_AddIsArchivedToBoard",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 28,
|
||||
"version": "7",
|
||||
"when": 1771930355536,
|
||||
"tag": "20260224105235_AddGitHubIntegrationSupport",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ export const getAllByWorkspaceId = async (
|
||||
db: dbClient,
|
||||
workspaceId: number,
|
||||
userId: string,
|
||||
opts?: { type?: "regular" | "template" },
|
||||
opts?: { type?: "regular" | "template"; archived?: boolean },
|
||||
) => {
|
||||
const boardsData = await db.query.boards.findMany({
|
||||
columns: {
|
||||
@@ -78,6 +78,7 @@ export const getAllByWorkspaceId = async (
|
||||
eq(boards.workspaceId, workspaceId),
|
||||
isNull(boards.deletedAt),
|
||||
opts?.type ? eq(boards.type, opts.type) : undefined,
|
||||
opts?.archived !== undefined ? eq(boards.isArchived, opts.archived) : undefined,
|
||||
),
|
||||
});
|
||||
|
||||
@@ -102,6 +103,7 @@ export const getIdByPublicId = async (db: dbClient, boardPublicId: string) => {
|
||||
columns: {
|
||||
id: true,
|
||||
type: true,
|
||||
isArchived: true,
|
||||
},
|
||||
where: eq(boards.publicId, boardPublicId),
|
||||
});
|
||||
@@ -195,6 +197,7 @@ export const getByPublicId = async (
|
||||
name: true,
|
||||
slug: true,
|
||||
visibility: true,
|
||||
isArchived: true,
|
||||
},
|
||||
with: {
|
||||
userFavorites: {
|
||||
@@ -628,6 +631,7 @@ export const update = async (
|
||||
slug: string | undefined;
|
||||
visibility: BoardVisibilityStatus | undefined;
|
||||
boardPublicId: string;
|
||||
isArchived?: boolean;
|
||||
},
|
||||
) => {
|
||||
const [result] = await db
|
||||
@@ -637,6 +641,7 @@ export const update = async (
|
||||
slug: boardInput.slug,
|
||||
visibility: boardInput.visibility,
|
||||
updatedAt: new Date(),
|
||||
...(boardInput.isArchived !== undefined && { isArchived: boardInput.isArchived })
|
||||
})
|
||||
.where(eq(boards.publicId, boardInput.boardPublicId))
|
||||
.returning({
|
||||
|
||||
@@ -46,6 +46,35 @@ export const getProvidersForUser = async (db: dbClient, userId: string) => {
|
||||
return integration;
|
||||
};
|
||||
|
||||
export const createOrUpdateProvider = async (
|
||||
db: dbClient,
|
||||
data: {
|
||||
userId: string;
|
||||
provider: string;
|
||||
accessToken: string;
|
||||
refreshToken?: string | null;
|
||||
expiresAt: Date;
|
||||
},
|
||||
) => {
|
||||
await db
|
||||
.insert(integrations)
|
||||
.values({
|
||||
provider: data.provider,
|
||||
userId: data.userId,
|
||||
accessToken: data.accessToken,
|
||||
refreshToken: data.refreshToken ?? null,
|
||||
expiresAt: data.expiresAt,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: [integrations.userId, integrations.provider],
|
||||
set: {
|
||||
accessToken: data.accessToken,
|
||||
refreshToken: data.refreshToken ?? null,
|
||||
expiresAt: data.expiresAt,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteProviderForUser = async (
|
||||
db: dbClient,
|
||||
userId: string,
|
||||
|
||||
@@ -30,22 +30,22 @@ const SYSTEM_ROLES: {
|
||||
description: string;
|
||||
hierarchyLevel: number;
|
||||
}[] = [
|
||||
{
|
||||
name: "admin",
|
||||
description: "Full access to all workspace features",
|
||||
hierarchyLevel: 100,
|
||||
},
|
||||
{
|
||||
name: "member",
|
||||
description: "Standard member with create and edit permissions",
|
||||
hierarchyLevel: 50,
|
||||
},
|
||||
{
|
||||
name: "guest",
|
||||
description: "View-only access",
|
||||
hierarchyLevel: 10,
|
||||
},
|
||||
];
|
||||
{
|
||||
name: "admin",
|
||||
description: "Full access to all workspace features",
|
||||
hierarchyLevel: 100,
|
||||
},
|
||||
{
|
||||
name: "member",
|
||||
description: "Standard member with create and edit permissions",
|
||||
hierarchyLevel: 50,
|
||||
},
|
||||
{
|
||||
name: "guest",
|
||||
description: "View-only access",
|
||||
hierarchyLevel: 10,
|
||||
},
|
||||
];
|
||||
|
||||
export const getCount = async (db: dbClient) => {
|
||||
const result = await db
|
||||
@@ -250,7 +250,7 @@ export const getBySlugWithBoards = (db: dbClient, workspaceSlug: string) => {
|
||||
slug: true,
|
||||
name: true,
|
||||
},
|
||||
where: and(isNull(boards.deletedAt), eq(boards.visibility, "public")),
|
||||
where: and(isNull(boards.deletedAt), eq(boards.visibility, "public"), eq(boards.isArchived, false)),
|
||||
orderBy: [asc(boards.name)]
|
||||
},
|
||||
},
|
||||
|
||||
@@ -2,7 +2,6 @@ import { relations, sql } from "drizzle-orm";
|
||||
import {
|
||||
bigint,
|
||||
bigserial,
|
||||
boolean,
|
||||
index,
|
||||
pgEnum,
|
||||
pgTable,
|
||||
@@ -12,8 +11,8 @@ import {
|
||||
uniqueIndex,
|
||||
uuid,
|
||||
varchar,
|
||||
boolean,
|
||||
} from "drizzle-orm/pg-core";
|
||||
|
||||
import { imports } from "./imports";
|
||||
import { labels } from "./labels";
|
||||
import { lists } from "./lists";
|
||||
@@ -56,9 +55,11 @@ export const boards = pgTable(
|
||||
.references(() => workspaces.id, { onDelete: "cascade" }),
|
||||
visibility: boardVisibilityEnum("visibility").notNull().default("private"),
|
||||
type: boardTypeEnum("type").notNull().default("regular"),
|
||||
isArchived: boolean("isArchived").notNull().default(false),
|
||||
sourceBoardId: bigint("sourceBoardId", { mode: "number" }),
|
||||
},
|
||||
(table) => [
|
||||
index("board_is_archived_idx").on(table.isArchived),
|
||||
index("board_visibility_idx").on(table.visibility),
|
||||
index("board_type_idx").on(table.type),
|
||||
index("board_source_idx").on(table.sourceBoardId),
|
||||
|
||||
@@ -14,7 +14,7 @@ import { labels } from "./labels";
|
||||
import { lists } from "./lists";
|
||||
import { users } from "./users";
|
||||
|
||||
export const importSourceEnum = pgEnum("source", ["trello"]);
|
||||
export const importSourceEnum = pgEnum("source", ["trello", "github"]);
|
||||
export const importStatusEnum = pgEnum("status", [
|
||||
"started",
|
||||
"success",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { relations } from "drizzle-orm";
|
||||
import {
|
||||
pgTable,
|
||||
primaryKey,
|
||||
text,
|
||||
timestamp,
|
||||
uuid,
|
||||
varchar,
|
||||
@@ -16,7 +17,7 @@ export const integrations = pgTable(
|
||||
userId: uuid("userId")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
accessToken: varchar("accessToken", { length: 255 }).notNull(),
|
||||
accessToken: text("accessToken").notNull(),
|
||||
refreshToken: varchar("refreshToken", { length: 255 }),
|
||||
expiresAt: timestamp("expiresAt").notNull(),
|
||||
createdAt: timestamp("createdAt")
|
||||
|
||||
Reference in New Issue
Block a user