Compare commits
22 Commits
fix/api-ke
...
fix/create
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f4f507b58 | ||
|
|
d839195ad2 | ||
|
|
9815b5f273 | ||
|
|
25490b2223 | ||
|
|
b3108942db | ||
|
|
2ba759966e | ||
|
|
7045cd8e25 | ||
|
|
603cc46b7d | ||
|
|
e9d338384a | ||
|
|
8a2a9ecef5 | ||
|
|
3a44957662 | ||
|
|
20e6c99e32 | ||
|
|
c0aae5449f | ||
|
|
596f346181 | ||
|
|
7b59e2ac07 | ||
|
|
2a9b1fd2b5 | ||
|
|
a2d4314e14 | ||
|
|
f94e4d6da2 | ||
|
|
97f4defc0e | ||
|
|
dd29dc89fd | ||
|
|
486cdf8313 | ||
|
|
67cf523ee8 |
@@ -11,10 +11,10 @@ https://kan.bn/api/v1
|
||||
|
||||
## Authentication
|
||||
|
||||
Most endpoints require authentication using your API key. You can create one in the [settings page](https://kan.bn/settings) of your account. Include this key in the `x-api-key` header of each request.
|
||||
Most endpoints require authentication using your API key. You can create one in the [settings page](https://kan.bn/settings) of your account. Include this key as a Bearer token in the `Authorization` header of each request.
|
||||
|
||||
```
|
||||
'x-api-key': kan_123456789
|
||||
'Authorization': 'Bearer kan_123456789'
|
||||
```
|
||||
|
||||
## Response codes
|
||||
|
||||
@@ -103,6 +103,9 @@ checksums:
|
||||
tMYIu7/message: 8b1f0bb96a905646ecfad1cfdfa42168
|
||||
tMYIu7/origin/0/0: d77eb1f90f2fa86a55181629d88d237a
|
||||
tMYIu7/translation: 8b1f0bb96a905646ecfad1cfdfa42168
|
||||
UGCIzB/message: f7b6699c16726afc48f1e1d1339b2e7e
|
||||
UGCIzB/origin/0/0: 0eeeb7e68164ff118040918f1ef00a7a
|
||||
UGCIzB/translation: f7b6699c16726afc48f1e1d1339b2e7e
|
||||
B3xxao/message: 9d80becc4fe65a74e0004e4fd290735d
|
||||
B3xxao/origin/0/0: 6812b79a8fdc3527586b523d4c137340
|
||||
B3xxao/translation: 9d80becc4fe65a74e0004e4fd290735d
|
||||
@@ -235,6 +238,9 @@ checksums:
|
||||
ZXSPJt/message: 1b5749b0cca6a62d75a577bee6804074
|
||||
ZXSPJt/origin/0/0: 0627e0040ca4939c9a57349e98c51797
|
||||
ZXSPJt/translation: 1b5749b0cca6a62d75a577bee6804074
|
||||
YkfDoz/translation: 5d4f1c56f4e9e579ec9967ca68cc64ac
|
||||
YkfDoz/message: 5d4f1c56f4e9e579ec9967ca68cc64ac
|
||||
YkfDoz/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
3bqt9U/message: 2366ed295eb2c03c425559c24cb31606
|
||||
3bqt9U/origin/0/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
3bqt9U/translation: 2366ed295eb2c03c425559c24cb31606
|
||||
@@ -316,6 +322,9 @@ checksums:
|
||||
1rWxEw/message: 122c108794f321c10e05a08f09b11457
|
||||
1rWxEw/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
1rWxEw/translation: 122c108794f321c10e05a08f09b11457
|
||||
iH8pgl/translation: f541015a827e37cb3b1234e56bc2aa3c
|
||||
iH8pgl/message: f541015a827e37cb3b1234e56bc2aa3c
|
||||
iH8pgl/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
KNKCTb/message: 35919fd5b10ad212839a75e72829fe4e
|
||||
KNKCTb/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
KNKCTb/translation: 35919fd5b10ad212839a75e72829fe4e
|
||||
@@ -334,6 +343,9 @@ checksums:
|
||||
UoSI%2Bi/message: 47f1051a134e111930be7f94179df4c8
|
||||
UoSI%2Bi/origin/0/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
UoSI%2Bi/translation: 47f1051a134e111930be7f94179df4c8
|
||||
zt%2F6cS/translation: aadb69a7f7421be6bb022fbde08a6d77
|
||||
zt%2F6cS/message: aadb69a7f7421be6bb022fbde08a6d77
|
||||
zt%2F6cS/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
qaS%2B1%2F/message: 4e25347caf65e1b63bec90e101b86ddd
|
||||
qaS%2B1%2F/origin/0/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
qaS%2B1%2F/translation: 4e25347caf65e1b63bec90e101b86ddd
|
||||
@@ -516,23 +528,28 @@ checksums:
|
||||
dEgA5A/message: 2e2a849c2223911717de8caa2c71bade
|
||||
dEgA5A/origin/0/0: cf5db0532c4f1cf49cebe78926c03385
|
||||
dEgA5A/origin/1/0: a50c4fbde8da6e0a77c4e0aef0b44dea
|
||||
dEgA5A/origin/2/0: 522726bb62051656dc0d165185d6b451
|
||||
dEgA5A/origin/3/0: b2059fa4b8b99cc10440da26475b234c
|
||||
dEgA5A/origin/4/0: 2a382c1cdf010f01a8e95c3e05f6df53
|
||||
dEgA5A/origin/5/0: d55f532bb5ae247e3a018978be0da463
|
||||
dEgA5A/origin/6/0: 4b4f55c033add8db69178563832227c6
|
||||
dEgA5A/origin/7/0: 68450df287fb46ea629e818732c1291a
|
||||
dEgA5A/origin/8/0: 03c00909b41be01231cd3e843c8ee44e
|
||||
dEgA5A/origin/9/0: 0627e0040ca4939c9a57349e98c51797
|
||||
dEgA5A/origin/10/0: 15792234f408027822ee71ccddde6f9b
|
||||
dEgA5A/origin/11/0: 5c60161e173f5eae9276d8e4c70b4ebb
|
||||
dEgA5A/origin/12/0: a1fde3fcce608870830f168f027727ff
|
||||
dEgA5A/origin/13/0: 83911e3eacbad4583e2b1647a784d154
|
||||
dEgA5A/origin/14/0: dbad0c8d7863cb41f5495264f82e7081
|
||||
dEgA5A/origin/2/0: 97bd206a05414e2a571020d64e166093
|
||||
dEgA5A/origin/3/0: 522726bb62051656dc0d165185d6b451
|
||||
dEgA5A/origin/4/0: b2059fa4b8b99cc10440da26475b234c
|
||||
dEgA5A/origin/5/0: 2a382c1cdf010f01a8e95c3e05f6df53
|
||||
dEgA5A/origin/6/0: d55f532bb5ae247e3a018978be0da463
|
||||
dEgA5A/origin/7/0: 4b4f55c033add8db69178563832227c6
|
||||
dEgA5A/origin/8/0: 68450df287fb46ea629e818732c1291a
|
||||
dEgA5A/origin/9/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
dEgA5A/origin/10/0: 03c00909b41be01231cd3e843c8ee44e
|
||||
dEgA5A/origin/11/0: 0627e0040ca4939c9a57349e98c51797
|
||||
dEgA5A/origin/12/0: 15792234f408027822ee71ccddde6f9b
|
||||
dEgA5A/origin/13/0: 5c60161e173f5eae9276d8e4c70b4ebb
|
||||
dEgA5A/origin/14/0: a1fde3fcce608870830f168f027727ff
|
||||
dEgA5A/origin/15/0: 83911e3eacbad4583e2b1647a784d154
|
||||
dEgA5A/origin/16/0: dbad0c8d7863cb41f5495264f82e7081
|
||||
dEgA5A/translation: 2e2a849c2223911717de8caa2c71bade
|
||||
kryGs%2B/message: bba0beaced7ea954ceb980f2b022ffee
|
||||
kryGs%2B/origin/0/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
kryGs%2B/translation: bba0beaced7ea954ceb980f2b022ffee
|
||||
sU2uWc/message: 3fe52244676faf64e5266b6713d01e07
|
||||
sU2uWc/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
sU2uWc/translation: 3fe52244676faf64e5266b6713d01e07
|
||||
fEY2vP/message: 91509e2f92b0b3b11330b6983139fdbf
|
||||
fEY2vP/origin/0/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
fEY2vP/origin/1/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
@@ -541,8 +558,9 @@ checksums:
|
||||
ZH7TVS/origin/0/0: 984122104bcc6d8fa6d4c8a35e7751d2
|
||||
ZH7TVS/translation: 7c34f59f4005e6cb3a6ff546ea0b96e3
|
||||
rQXTmd/message: 9387a4702b302f23f2f7c20b73a2b3dd
|
||||
rQXTmd/origin/0/0: 1b05beba6bdd908015fa8e798717f024
|
||||
rQXTmd/origin/1/0: 9c8b544f5db130cd7c5eda9064ba3957
|
||||
rQXTmd/origin/0/0: fc0c18a095a68277a0f90a115942683b
|
||||
rQXTmd/origin/1/0: 1b05beba6bdd908015fa8e798717f024
|
||||
rQXTmd/origin/2/0: 9c8b544f5db130cd7c5eda9064ba3957
|
||||
rQXTmd/translation: 9387a4702b302f23f2f7c20b73a2b3dd
|
||||
VhMDMg/message: a552fc5c4189ebc3e2e6018edda7d18f
|
||||
VhMDMg/origin/0/0: 627b72cd19a7154ae1c28cbd7ca0c730
|
||||
@@ -550,9 +568,9 @@ checksums:
|
||||
VhMDMg/origin/2/0: 0627e0040ca4939c9a57349e98c51797
|
||||
VhMDMg/origin/3/0: 0627e0040ca4939c9a57349e98c51797
|
||||
VhMDMg/translation: a552fc5c4189ebc3e2e6018edda7d18f
|
||||
fzGyWs/translation: 25dbbca7a83f6af119179e7a56c953d4
|
||||
fzGyWs/message: 25dbbca7a83f6af119179e7a56c953d4
|
||||
fzGyWs/origin/0/0: 627b72cd19a7154ae1c28cbd7ca0c730
|
||||
fzGyWs/translation: 25dbbca7a83f6af119179e7a56c953d4
|
||||
yD3ZSw/message: 293d49fc3c75e9c425b64bd7126e6b46
|
||||
yD3ZSw/origin/0/0: 627b72cd19a7154ae1c28cbd7ca0c730
|
||||
yD3ZSw/translation: 293d49fc3c75e9c425b64bd7126e6b46
|
||||
@@ -575,6 +593,9 @@ checksums:
|
||||
EH8IL3/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
EH8IL3/origin/1/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
EH8IL3/translation: 6f79129c8f08ee54d858a2af57d16dd9
|
||||
zMquA7/translation: 38ff8d574865bb71d2f620bc4ba98c20
|
||||
zMquA7/message: 38ff8d574865bb71d2f620bc4ba98c20
|
||||
zMquA7/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
VHS0aJ/message: 31d0962985c83a29558c98a765bb1b16
|
||||
VHS0aJ/origin/0/0: 15792234f408027822ee71ccddde6f9b
|
||||
VHS0aJ/translation: 31d0962985c83a29558c98a765bb1b16
|
||||
@@ -680,6 +701,10 @@ checksums:
|
||||
AX4ktp/message: 4e6be22ade0188f408471325fe363575
|
||||
AX4ktp/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
AX4ktp/translation: 4e6be22ade0188f408471325fe363575
|
||||
xGVfLh/translation: 3cfba90b4600131e82fc4260c568d044
|
||||
xGVfLh/message: 3cfba90b4600131e82fc4260c568d044
|
||||
xGVfLh/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
xGVfLh/origin/1/0: 69d8634b177fdf937764b406fd477547
|
||||
J2Wbjt/message: 8ed03cf7c5e60a6edf3470a4558ff058
|
||||
J2Wbjt/origin/0/0: d96af8a06c2e38a72238bcd16e426859
|
||||
J2Wbjt/translation: 8ed03cf7c5e60a6edf3470a4558ff058
|
||||
@@ -699,6 +724,18 @@ checksums:
|
||||
F0YmUY/message: 9def232c9163d109f0e9093684cfe75f
|
||||
F0YmUY/origin/0/0: 1b05beba6bdd908015fa8e798717f024
|
||||
F0YmUY/translation: 9def232c9163d109f0e9093684cfe75f
|
||||
0utuU6/message: 9d7e453b24dfaf217352aeadc262074d
|
||||
0utuU6/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
0utuU6/translation: 9d7e453b24dfaf217352aeadc262074d
|
||||
fDQ7hA/message: 1d24ecbad9f2f0081ab51c7366e40506
|
||||
fDQ7hA/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
fDQ7hA/translation: 1d24ecbad9f2f0081ab51c7366e40506
|
||||
1bJKhj/message: f61803ac8da8253e4ba35f92b3af1101
|
||||
1bJKhj/origin/0/0: 0eeeb7e68164ff118040918f1ef00a7a
|
||||
1bJKhj/translation: f61803ac8da8253e4ba35f92b3af1101
|
||||
uvH2xS/message: ecc2617544a6d385d18678577fa112fd
|
||||
uvH2xS/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
uvH2xS/translation: ecc2617544a6d385d18678577fa112fd
|
||||
9PaIxv/message: da95932e7a1465a5d21aa3b855a46dc2
|
||||
9PaIxv/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
9PaIxv/translation: da95932e7a1465a5d21aa3b855a46dc2
|
||||
@@ -795,6 +832,9 @@ checksums:
|
||||
7RpHg%2F/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
7RpHg%2F/origin/1/0: c0b59968b2b234167c488a05cc38710b
|
||||
7RpHg%2F/translation: 66f702512197d25cfdb117f2415ecd88
|
||||
ZDPJBc/translation: f9154d0c02a7db907f0a33fb5edd4be1
|
||||
ZDPJBc/message: f9154d0c02a7db907f0a33fb5edd4be1
|
||||
ZDPJBc/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
j9IZZ0/message: 7ba841d0946eb04fa3d17d74365be37b
|
||||
j9IZZ0/origin/0/0: ff4a160eca5f8da4f075fd1dd6061fa6
|
||||
j9IZZ0/origin/1/0: dbad0c8d7863cb41f5495264f82e7081
|
||||
@@ -838,7 +878,8 @@ checksums:
|
||||
tmpW%2Bw/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
tmpW%2Bw/translation: e915cd160651ad4b61a67e8da0737c23
|
||||
nabda1/message: 18811ccf76fbb7a2772d648f7c5f0ea7
|
||||
nabda1/origin/0/0: 1b05beba6bdd908015fa8e798717f024
|
||||
nabda1/origin/0/0: 0eeeb7e68164ff118040918f1ef00a7a
|
||||
nabda1/origin/1/0: 1b05beba6bdd908015fa8e798717f024
|
||||
nabda1/translation: 18811ccf76fbb7a2772d648f7c5f0ea7
|
||||
njJFtc/message: a3dae0c9ddbc73677aad9812e3dffd69
|
||||
njJFtc/origin/0/0: b2059fa4b8b99cc10440da26475b234c
|
||||
@@ -919,12 +960,15 @@ checksums:
|
||||
vUr5JT/origin/0/0: 4a1be3707d14c696a16f453d132fb248
|
||||
vUr5JT/translation: 6ae8282ab8b4a01b4ce87b119e13714b
|
||||
DPfwMq/message: ffd408fa29d5bc9039ef8ea1b9b699bb
|
||||
DPfwMq/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
DPfwMq/origin/1/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
DPfwMq/origin/2/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
DPfwMq/origin/0/0: 81b173297e9c022d9ebde5f7018c95f9
|
||||
DPfwMq/origin/1/0: 120e67abaa784f3adb192e7519919a81
|
||||
DPfwMq/origin/2/0: fc68b5394b9b466d5d67df855060544d
|
||||
DPfwMq/origin/3/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
DPfwMq/origin/4/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
DPfwMq/origin/5/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
DPfwMq/origin/6/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
DPfwMq/origin/7/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
DPfwMq/origin/8/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
DPfwMq/translation: ffd408fa29d5bc9039ef8ea1b9b699bb
|
||||
R3FsF4/message: 142b391cca3e05f2af9617092f7358c5
|
||||
R3FsF4/origin/0/0: 3a89a46ac678e34dc8eb687b07a4ad4b
|
||||
@@ -946,6 +990,16 @@ checksums:
|
||||
zxKs%2By/message: 0b6c8ad7aba0873b7e212d5f1949ca97
|
||||
zxKs%2By/origin/0/0: db1e755dc7d73e037f425111bf7c30a6
|
||||
zxKs%2By/translation: 0b6c8ad7aba0873b7e212d5f1949ca97
|
||||
euc6Ns/message: 27756566785c2b8463e21582c4bb619b
|
||||
euc6Ns/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
euc6Ns/translation: 27756566785c2b8463e21582c4bb619b
|
||||
BTDPLo/message: f6a33afcf5ff1489551c94867e083dca
|
||||
BTDPLo/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
BTDPLo/origin/1/0: 0eeeb7e68164ff118040918f1ef00a7a
|
||||
BTDPLo/translation: f6a33afcf5ff1489551c94867e083dca
|
||||
06EQqT/message: e9f56489fb395a890ae2557200c29a36
|
||||
06EQqT/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
06EQqT/translation: e9f56489fb395a890ae2557200c29a36
|
||||
ePK91l/message: eee7f39ff90b18852afc1671f21fbaa9
|
||||
ePK91l/origin/0/0: b697a20a9536be4dd8ecd143461eafc7
|
||||
ePK91l/origin/1/0: dc1a240d2d0cccb102c67ca311d4e457
|
||||
@@ -992,6 +1046,12 @@ checksums:
|
||||
IqjpYe/message: 81d41cf573a7109c376d30d905beb596
|
||||
IqjpYe/origin/0/0: 5f6c4a0c9be5098099167871ae1564af
|
||||
IqjpYe/translation: 81d41cf573a7109c376d30d905beb596
|
||||
bFREhu/message: b2cc9a311fc28d1594252f697c7f5342
|
||||
bFREhu/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
bFREhu/translation: b2cc9a311fc28d1594252f697c7f5342
|
||||
SUXBxp/translation: 76e841ae8ec3340d7d0a5c2191abbea4
|
||||
SUXBxp/message: 76e841ae8ec3340d7d0a5c2191abbea4
|
||||
SUXBxp/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
0%2BewPp/message: 785fe23c0eef0a5b60b5b2a88151de31
|
||||
0%2BewPp/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
0%2BewPp/origin/1/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
@@ -1170,17 +1230,19 @@ checksums:
|
||||
l31EoQ/message: b4c05c9174637f4da2a41ead0d65bc01
|
||||
l31EoQ/origin/0/0: 4980d8e27a628e7cd9a70b839d844083
|
||||
l31EoQ/translation: b4c05c9174637f4da2a41ead0d65bc01
|
||||
q3il6U/translation: 79a4fffd70bfbedb6174ea4c767f4ab9
|
||||
q3il6U/message: 79a4fffd70bfbedb6174ea4c767f4ab9
|
||||
q3il6U/origin/0/0: 627b72cd19a7154ae1c28cbd7ca0c730
|
||||
q3il6U/translation: 79a4fffd70bfbedb6174ea4c767f4ab9
|
||||
"%2B3TYXa/message": 9fa1c942feb40d6350322b71561df789
|
||||
"%2B3TYXa/origin/0/0": 4980d8e27a628e7cd9a70b839d844083
|
||||
"%2B3TYXa/translation": 9fa1c942feb40d6350322b71561df789
|
||||
2POOFK/message: 0326365539c004f6088656f692602078
|
||||
2POOFK/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
2POOFK/origin/1/0: 9737a9cef0646ff4bbd942b1924b9a2c
|
||||
2POOFK/origin/2/0: 9737a9cef0646ff4bbd942b1924b9a2c
|
||||
2POOFK/origin/3/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
2POOFK/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
2POOFK/origin/1/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
2POOFK/origin/2/0: c0b59968b2b234167c488a05cc38710b
|
||||
2POOFK/origin/3/0: 9737a9cef0646ff4bbd942b1924b9a2c
|
||||
2POOFK/origin/4/0: 9737a9cef0646ff4bbd942b1924b9a2c
|
||||
2POOFK/origin/5/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
2POOFK/translation: 0326365539c004f6088656f692602078
|
||||
uP4V6I/message: 2d403501f0488ec7d4eac979faf051a2
|
||||
uP4V6I/origin/0/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
@@ -1270,6 +1332,9 @@ checksums:
|
||||
csFbe%2B/message: e4e58e33d637282d141df466d729bc7c
|
||||
csFbe%2B/origin/0/0: 94d3e20c29bb517dd394711d7524e478
|
||||
csFbe%2B/translation: e4e58e33d637282d141df466d729bc7c
|
||||
SUvm1Y/translation: 6c0f26526f77e9abb92fb2b1106a66db
|
||||
SUvm1Y/message: 6c0f26526f77e9abb92fb2b1106a66db
|
||||
SUvm1Y/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
cdyS7J/message: 0f10050aeed2555a34fe3c27ce616607
|
||||
cdyS7J/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
cdyS7J/origin/1/0: c0b59968b2b234167c488a05cc38710b
|
||||
@@ -1426,9 +1491,10 @@ checksums:
|
||||
h7MgpO/origin/0/0: feacdaf2791aaddec128f463ffa2e807
|
||||
h7MgpO/translation: ef00d7494b69def6841620bd6554d040
|
||||
h8DugX/message: 6f15627a90002323eac018274b6922d6
|
||||
h8DugX/origin/0/0: db1e755dc7d73e037f425111bf7c30a6
|
||||
h8DugX/origin/1/0: 984122104bcc6d8fa6d4c8a35e7751d2
|
||||
h8DugX/origin/2/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
h8DugX/origin/0/0: 120e67abaa784f3adb192e7519919a81
|
||||
h8DugX/origin/1/0: db1e755dc7d73e037f425111bf7c30a6
|
||||
h8DugX/origin/2/0: 984122104bcc6d8fa6d4c8a35e7751d2
|
||||
h8DugX/origin/3/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
h8DugX/translation: 6f15627a90002323eac018274b6922d6
|
||||
AZI%2Fwb/message: e1ceda0c6cc32fb04cb9423582ad8fe4
|
||||
AZI%2Fwb/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
@@ -1439,9 +1505,9 @@ checksums:
|
||||
vXIe7J/message: 277fd1a41cc237a437cd1d5e4a80463b
|
||||
vXIe7J/origin/0/0: 627b72cd19a7154ae1c28cbd7ca0c730
|
||||
vXIe7J/translation: 277fd1a41cc237a437cd1d5e4a80463b
|
||||
k7rCa%2F/translation: 890b7851af05f97ac53644e4154c13b4
|
||||
k7rCa%2F/message: 890b7851af05f97ac53644e4154c13b4
|
||||
k7rCa%2F/origin/0/0: 3de48fb04f7df9bdbe399911cdb3fe86
|
||||
k7rCa%2F/translation: 890b7851af05f97ac53644e4154c13b4
|
||||
8Is1ih/message: 624592ba2ecf647a3fe60d493c1ee71a
|
||||
8Is1ih/origin/0/0: ff4a160eca5f8da4f075fd1dd6061fa6
|
||||
8Is1ih/origin/1/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
@@ -1473,12 +1539,14 @@ checksums:
|
||||
TCt%2F8K/translation: ffd8033392a01d7b33f13afa51bccb9a
|
||||
edWbV6/message: 4a4805700b31ec65bcb3ca962bccfd1b
|
||||
edWbV6/origin/0/0: 85d0a3237fa9329fba3f0278a2cd7284
|
||||
edWbV6/origin/1/0: 1b05beba6bdd908015fa8e798717f024
|
||||
edWbV6/origin/2/0: 9c8b544f5db130cd7c5eda9064ba3957
|
||||
edWbV6/origin/3/0: faa8a2576972b4eb31565d8ea6098f43
|
||||
edWbV6/origin/1/0: fc0c18a095a68277a0f90a115942683b
|
||||
edWbV6/origin/2/0: 1b05beba6bdd908015fa8e798717f024
|
||||
edWbV6/origin/3/0: 9c8b544f5db130cd7c5eda9064ba3957
|
||||
edWbV6/origin/4/0: faa8a2576972b4eb31565d8ea6098f43
|
||||
edWbV6/translation: 4a4805700b31ec65bcb3ca962bccfd1b
|
||||
2BBAbc/message: 94f13e7ef909a4de9db7abaa1f9f0b61
|
||||
2BBAbc/origin/0/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
2BBAbc/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
2BBAbc/origin/1/0: 15fd9c05fc09ccbbb54aadc4aa5e5501
|
||||
2BBAbc/translation: 94f13e7ef909a4de9db7abaa1f9f0b61
|
||||
zQX5Dj/message: e925e2e6ccaf0eb4064a888aaea8d3c2
|
||||
zQX5Dj/origin/0/0: 5e445d66b146e0ca392faa35098701c4
|
||||
@@ -1516,6 +1584,10 @@ checksums:
|
||||
DbZgsJ/message: 7a1c63b75cea690b3fda6c3f203e31ff
|
||||
DbZgsJ/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
DbZgsJ/translation: 7a1c63b75cea690b3fda6c3f203e31ff
|
||||
hB02vO/message: c13aa2a155ab4aff1c8fed6650a94e1a
|
||||
hB02vO/origin/0/0: fc68b5394b9b466d5d67df855060544d
|
||||
hB02vO/origin/1/0: 0eeeb7e68164ff118040918f1ef00a7a
|
||||
hB02vO/translation: c13aa2a155ab4aff1c8fed6650a94e1a
|
||||
IDvohQ/message: 35d0822f65971b97774b962561b02649
|
||||
IDvohQ/origin/0/0: 1d6b5f88cdad160a67842f6b65387448
|
||||
IDvohQ/translation: 35d0822f65971b97774b962561b02649
|
||||
@@ -1523,9 +1595,12 @@ checksums:
|
||||
jl3aEJ/placeholders/0/0: 06f23520ebabfffed4999b5bcf61c9cd
|
||||
jl3aEJ/origin/0/0: 1d6b5f88cdad160a67842f6b65387448
|
||||
jl3aEJ/translation: 4c38799ff25321ea25017bf4cd8e2e4f
|
||||
agPptk/translation: 43983f2178fb28aacaef6c5f41282c4a
|
||||
vo2a%2Ba/translation: fcf0f06f8b64b458c7ca6d95541a3cc8
|
||||
vo2a%2Ba/message: fcf0f06f8b64b458c7ca6d95541a3cc8
|
||||
vo2a%2Ba/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
agPptk/message: 43983f2178fb28aacaef6c5f41282c4a
|
||||
agPptk/origin/0/0: 3de48fb04f7df9bdbe399911cdb3fe86
|
||||
agPptk/translation: 43983f2178fb28aacaef6c5f41282c4a
|
||||
W%2FElkg/message: 1f527cd6d1ed602930bcaa303f503b51
|
||||
W%2FElkg/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
W%2FElkg/translation: 1f527cd6d1ed602930bcaa303f503b51
|
||||
@@ -1553,12 +1628,19 @@ checksums:
|
||||
hty0d5/origin/0/0: 04c86ea96f180745739d59e822da4026
|
||||
hty0d5/translation: b4b1c8396e445e8b7956c747da2cf601
|
||||
"%2B8Nek%2F/message": 818f1192e32bb855597f930d3e78806e
|
||||
"%2B8Nek%2F/origin/0/0": 9737a9cef0646ff4bbd942b1924b9a2c
|
||||
"%2B8Nek%2F/origin/1/0": 82a5cf8d69f098641eb357bf102cd504
|
||||
"%2B8Nek%2F/origin/0/0": 15ea2dfd5eae4e05b226b1320103476e
|
||||
"%2B8Nek%2F/origin/1/0": 9737a9cef0646ff4bbd942b1924b9a2c
|
||||
"%2B8Nek%2F/origin/2/0": 82a5cf8d69f098641eb357bf102cd504
|
||||
"%2B8Nek%2F/translation": 818f1192e32bb855597f930d3e78806e
|
||||
vneRvS/message: e228107df80015377112d41f4f155cb3
|
||||
vneRvS/origin/0/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
vneRvS/translation: e228107df80015377112d41f4f155cb3
|
||||
51UCsN/message: ce14fde5e972c2b5276c25ddded817c4
|
||||
51UCsN/origin/0/0: 0eeeb7e68164ff118040918f1ef00a7a
|
||||
51UCsN/translation: ce14fde5e972c2b5276c25ddded817c4
|
||||
J4%2BOTA/message: 6ad27e803483208b5313660b7b5791d3
|
||||
J4%2BOTA/origin/0/0: fd0e66cef8d46e96bcf3143a12f9b6db
|
||||
J4%2BOTA/translation: 6ad27e803483208b5313660b7b5791d3
|
||||
BOqTi5/message: 11edf0427766c26db541d46379dc3c16
|
||||
BOqTi5/placeholders/0/0: 9db68a4b386b9fa1fd1d5797c32be100
|
||||
BOqTi5/placeholders/1/0: b837a9e8bd06b58be95699b3ee663f43
|
||||
@@ -1786,6 +1868,9 @@ checksums:
|
||||
8RdLDU/message: d7820b1bf4efecc61ed89234567aaa9c
|
||||
8RdLDU/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
8RdLDU/translation: d7820b1bf4efecc61ed89234567aaa9c
|
||||
Oi%2BJ%2BN/translation: 313804fe615d51e0f0cbd599161d1ade
|
||||
Oi%2BJ%2BN/message: 313804fe615d51e0f0cbd599161d1ade
|
||||
Oi%2BJ%2BN/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
Iqh0Uv/message: 0cc9dcd6ac624383e9977f66d4b3b777
|
||||
Iqh0Uv/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
Iqh0Uv/origin/1/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
@@ -1858,25 +1943,33 @@ checksums:
|
||||
tyHiOa/origin/36/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
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/origin/39/0: 69d8634b177fdf937764b406fd477547
|
||||
tyHiOa/origin/40/0: 69d8634b177fdf937764b406fd477547
|
||||
tyHiOa/origin/41/0: 03c00909b41be01231cd3e843c8ee44e
|
||||
tyHiOa/origin/42/0: 5c60161e173f5eae9276d8e4c70b4ebb
|
||||
tyHiOa/origin/43/0: 83911e3eacbad4583e2b1647a784d154
|
||||
tyHiOa/origin/44/0: d465da67c0a870d198eb7f313569c137
|
||||
tyHiOa/origin/45/0: 33bf266228f835e12c0bfb0e5efb3be9
|
||||
tyHiOa/origin/46/0: ff48991e314b0b3e989a4dac59860fd5
|
||||
tyHiOa/origin/47/0: 30791e26a172d47d3cb0693e82679246
|
||||
tyHiOa/origin/48/0: dbad0c8d7863cb41f5495264f82e7081
|
||||
tyHiOa/origin/49/0: 0dccc39d0debbf3e089cb6d292de762b
|
||||
tyHiOa/translation: 21ffcf0b00e7cd7b64f7454a95762e1d
|
||||
PZCqeW/message: 325dea6dd0348a27a6818db2c1340c98
|
||||
PZCqeW/origin/0/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
PZCqeW/origin/1/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
PZCqeW/translation: 325dea6dd0348a27a6818db2c1340c98
|
||||
fuwKpE/message: 346a18a54564881c888b95873d03df44
|
||||
fuwKpE/origin/0/0: 1b05beba6bdd908015fa8e798717f024
|
||||
fuwKpE/origin/1/0: 9c8b544f5db130cd7c5eda9064ba3957
|
||||
fuwKpE/origin/2/0: faa8a2576972b4eb31565d8ea6098f43
|
||||
fuwKpE/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
fuwKpE/origin/1/0: fd0e66cef8d46e96bcf3143a12f9b6db
|
||||
fuwKpE/origin/2/0: fc0c18a095a68277a0f90a115942683b
|
||||
fuwKpE/origin/3/0: 1b05beba6bdd908015fa8e798717f024
|
||||
fuwKpE/origin/4/0: 9c8b544f5db130cd7c5eda9064ba3957
|
||||
fuwKpE/origin/5/0: faa8a2576972b4eb31565d8ea6098f43
|
||||
fuwKpE/translation: 346a18a54564881c888b95873d03df44
|
||||
nYNMZZ/message: d5a8a1b38eaf02d02cd6ac2211b42a92
|
||||
nYNMZZ/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
nYNMZZ/translation: d5a8a1b38eaf02d02cd6ac2211b42a92
|
||||
aHCEmh/message: ce27f1aeacccc542a174c4b2bce022b0
|
||||
aHCEmh/origin/0/0: 98e2302d0d8d12ce65c4140b87450673
|
||||
aHCEmh/origin/1/0: 634473ef965836871efe40875a36b6ab
|
||||
@@ -1898,8 +1991,9 @@ checksums:
|
||||
zwBp5t/origin/0/0: d6920b20329a9efe5985a39a295d83e1
|
||||
zwBp5t/translation: d740d0660e68c61db1853489356030ae
|
||||
3fPjUY/message: 682b3c9feab30112b4454cb5bb7974b1
|
||||
3fPjUY/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
3fPjUY/origin/1/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
3fPjUY/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
3fPjUY/origin/1/0: c0b59968b2b234167c488a05cc38710b
|
||||
3fPjUY/origin/2/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
3fPjUY/translation: 682b3c9feab30112b4454cb5bb7974b1
|
||||
oyRjD%2F/message: 76a09fd843b496610f8cf1dced417b62
|
||||
oyRjD%2F/origin/0/0: 7493592314bc3b96ad96127a949ba1ba
|
||||
@@ -2009,6 +2103,7 @@ checksums:
|
||||
"%2FgaSVU/origin/0/0": 98e2302d0d8d12ce65c4140b87450673
|
||||
"%2FgaSVU/origin/1/0": 634473ef965836871efe40875a36b6ab
|
||||
"%2FgaSVU/origin/2/0": 634473ef965836871efe40875a36b6ab
|
||||
"%2FgaSVU/origin/3/0": 69d8634b177fdf937764b406fd477547
|
||||
"%2FgaSVU/translation": c60f4a1acf30e566861bf130f13b9ae7
|
||||
GDvlUT/message: 53743bbb6ca938f5b893552e839d067f
|
||||
GDvlUT/origin/0/0: 7493592314bc3b96ad96127a949ba1ba
|
||||
@@ -2057,6 +2152,9 @@ checksums:
|
||||
K3iLeO/message: e3bf6f95419169f460fb6918a0afc512
|
||||
K3iLeO/origin/0/0: 5e2ed4920ffd2f535ece848ff44900bd
|
||||
K3iLeO/translation: e3bf6f95419169f460fb6918a0afc512
|
||||
zYRVNp/message: 8b36455dd5b43e56d2ab06e522c3bacc
|
||||
zYRVNp/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
zYRVNp/translation: 8b36455dd5b43e56d2ab06e522c3bacc
|
||||
wgNoIs/message: eedc7cdb02de467c15dc418a066a77f2
|
||||
wgNoIs/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
wgNoIs/origin/1/0: 3c57a918258af4b44c187f58d203345f
|
||||
@@ -2086,11 +2184,16 @@ checksums:
|
||||
v3YoMA/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
v3YoMA/translation: 3fff865dc00435f82896fc302ea45630
|
||||
8AbRER/message: 3cb81c4829857556f5d117c9a23f7bcc
|
||||
8AbRER/origin/0/0: 2201bf679c663a732d7f1b3c3ce3897f
|
||||
8AbRER/origin/0/0: 81b173297e9c022d9ebde5f7018c95f9
|
||||
8AbRER/origin/1/0: 0eeeb7e68164ff118040918f1ef00a7a
|
||||
8AbRER/origin/2/0: 2201bf679c663a732d7f1b3c3ce3897f
|
||||
8AbRER/translation: 3cb81c4829857556f5d117c9a23f7bcc
|
||||
Eit43O/message: b5d9a1edd988f455041aee9fa7fb3d63
|
||||
Eit43O/origin/0/0: 1d6b5f88cdad160a67842f6b65387448
|
||||
Eit43O/translation: b5d9a1edd988f455041aee9fa7fb3d63
|
||||
JjEJSy/translation: 0154ff378b3f4329871378229e269fc7
|
||||
JjEJSy/message: 0154ff378b3f4329871378229e269fc7
|
||||
JjEJSy/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
Tz0i8g/message: 8df6777277469c1fd88cc18dde2f1cc3
|
||||
Tz0i8g/origin/0/0: 77c9f6139024b2069e4fdc5120f69cb5
|
||||
Tz0i8g/origin/1/0: 94d3e20c29bb517dd394711d7524e478
|
||||
@@ -2125,6 +2228,10 @@ checksums:
|
||||
n1ekoW/message: ec7b8f314fe9bc6591006707484ede61
|
||||
n1ekoW/origin/0/0: 6cda8b872e4902cbc0191d9375adf4ef
|
||||
n1ekoW/translation: ec7b8f314fe9bc6591006707484ede61
|
||||
fcWrnU/translation: 6d842546a84e919c519bf8cbffdf25a0
|
||||
fcWrnU/message: 6d842546a84e919c519bf8cbffdf25a0
|
||||
fcWrnU/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
fcWrnU/origin/1/0: 69d8634b177fdf937764b406fd477547
|
||||
mErq7F/message: 0dd2ae69be4618c1f9e615774a4509ca
|
||||
mErq7F/origin/0/0: 6cda8b872e4902cbc0191d9375adf4ef
|
||||
mErq7F/translation: 0dd2ae69be4618c1f9e615774a4509ca
|
||||
@@ -2151,15 +2258,18 @@ checksums:
|
||||
zEcnBA/message: 513c3b4d9f0fda60fe079d42dcbd3882
|
||||
zEcnBA/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
zEcnBA/translation: 513c3b4d9f0fda60fe079d42dcbd3882
|
||||
4Revpc/translation: 3adb3ae7891c5736776df840cff2360b
|
||||
4Revpc/message: 3adb3ae7891c5736776df840cff2360b
|
||||
4Revpc/origin/0/0: 3de48fb04f7df9bdbe399911cdb3fe86
|
||||
4Revpc/translation: 3adb3ae7891c5736776df840cff2360b
|
||||
"%2B%2BrVAm/message": 2227508afb0d38a027e323207e47d4a2
|
||||
"%2B%2BrVAm/origin/0/0": eb63312c63f6c8d2a5b6520c89012123
|
||||
"%2B%2BrVAm/translation": 2227508afb0d38a027e323207e47d4a2
|
||||
wIb7Ng/message: 67659097ef6bcb194839858b2c4f3a3c
|
||||
wIb7Ng/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
wIb7Ng/translation: 67659097ef6bcb194839858b2c4f3a3c
|
||||
6sKjjx/translation: 50861c0881fe87a77412417e5ffb3fbb
|
||||
6sKjjx/message: 50861c0881fe87a77412417e5ffb3fbb
|
||||
6sKjjx/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
vnS6Rf/message: 003f7f93d44b0f5c2e40bf24e7af3bd7
|
||||
vnS6Rf/origin/0/0: c0b59968b2b234167c488a05cc38710b
|
||||
vnS6Rf/translation: 003f7f93d44b0f5c2e40bf24e7af3bd7
|
||||
@@ -2199,6 +2309,9 @@ checksums:
|
||||
D%2BNlUC/message: 803281c327a02a2feba182f4a2b38311
|
||||
D%2BNlUC/origin/0/0: 358ea1b5babb2e9ccbf1a4c9f89dd3a5
|
||||
D%2BNlUC/translation: 803281c327a02a2feba182f4a2b38311
|
||||
KM6m8p/translation: c621ea9404a37af289def443b309bf1b
|
||||
KM6m8p/message: c621ea9404a37af289def443b309bf1b
|
||||
KM6m8p/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
bff61F/message: 3f0ae9c914f16ceb9a0d7db868f4aa20
|
||||
bff61F/origin/0/0: 8628ddb6f4ded25c0f17e2cbda8207d3
|
||||
bff61F/origin/1/0: 7493592314bc3b96ad96127a949ba1ba
|
||||
@@ -2250,6 +2363,9 @@ checksums:
|
||||
C6gv54/message: 1573c77059bc92df17e661befda8d9b7
|
||||
C6gv54/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
C6gv54/translation: 1573c77059bc92df17e661befda8d9b7
|
||||
nKBUeF/message: 07e3ce10820b8ab28643e38b2ed51f64
|
||||
nKBUeF/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
nKBUeF/translation: 07e3ce10820b8ab28643e38b2ed51f64
|
||||
jlB2RY/message: 67a76bf346ab4b48563269e9d941a64a
|
||||
jlB2RY/origin/0/0: 0627e0040ca4939c9a57349e98c51797
|
||||
jlB2RY/translation: 67a76bf346ab4b48563269e9d941a64a
|
||||
@@ -2301,6 +2417,12 @@ checksums:
|
||||
vlxQFL/message: 730f33b8f1fc002c4f393ccd262b6664
|
||||
vlxQFL/origin/0/0: afee530613110e248ffde6b56872ebed
|
||||
vlxQFL/translation: 730f33b8f1fc002c4f393ccd262b6664
|
||||
HQVm6e/translation: ec66b543a593e9dabf47de5979892d8d
|
||||
HQVm6e/message: ec66b543a593e9dabf47de5979892d8d
|
||||
HQVm6e/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
gKmoow/translation: 83997c77cb0dc8c8c90f7ab706aa817f
|
||||
gKmoow/message: 83997c77cb0dc8c8c90f7ab706aa817f
|
||||
gKmoow/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
OAYToL/message: 1c989752736fa41ecdd68ea890f16a15
|
||||
OAYToL/origin/0/0: 15792234f408027822ee71ccddde6f9b
|
||||
OAYToL/translation: 1c989752736fa41ecdd68ea890f16a15
|
||||
@@ -2322,6 +2444,9 @@ checksums:
|
||||
MHrjPM/message: 344e64395eaff6822a57d18623853e1a
|
||||
MHrjPM/origin/0/0: a50c4fbde8da6e0a77c4e0aef0b44dea
|
||||
MHrjPM/translation: 344e64395eaff6822a57d18623853e1a
|
||||
wK4OTM/message: b2a89bfd8e13d77f626e84840602a603
|
||||
wK4OTM/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
wK4OTM/translation: b2a89bfd8e13d77f626e84840602a603
|
||||
Se%2FUIp/message: d60813ea824f373462471e092d136eed
|
||||
Se%2FUIp/origin/0/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
Se%2FUIp/origin/1/0: eb63312c63f6c8d2a5b6520c89012123
|
||||
@@ -2364,9 +2489,10 @@ checksums:
|
||||
LeM5RY/origin/0/0: 0dccc39d0debbf3e089cb6d292de762b
|
||||
LeM5RY/translation: dfeac280858332082ad34d2623a59863
|
||||
W1ewR0/message: ddcac5d14d48358b043a9487b42eec16
|
||||
W1ewR0/origin/0/0: 1b05beba6bdd908015fa8e798717f024
|
||||
W1ewR0/origin/1/0: 9c8b544f5db130cd7c5eda9064ba3957
|
||||
W1ewR0/origin/2/0: faa8a2576972b4eb31565d8ea6098f43
|
||||
W1ewR0/origin/0/0: fc0c18a095a68277a0f90a115942683b
|
||||
W1ewR0/origin/1/0: 1b05beba6bdd908015fa8e798717f024
|
||||
W1ewR0/origin/2/0: 9c8b544f5db130cd7c5eda9064ba3957
|
||||
W1ewR0/origin/3/0: faa8a2576972b4eb31565d8ea6098f43
|
||||
W1ewR0/translation: ddcac5d14d48358b043a9487b42eec16
|
||||
zl1b97/message: 90112ea12ec6fa42097a6e022ae048a4
|
||||
zl1b97/origin/0/0: 984122104bcc6d8fa6d4c8a35e7751d2
|
||||
@@ -2383,6 +2509,7 @@ checksums:
|
||||
YcyP2z/translation: 7495f1434c9188849bffd015811d5337
|
||||
MxQXhL/message: c1c949477e121d73ed6683eddf9cd874
|
||||
MxQXhL/origin/0/0: ff4a160eca5f8da4f075fd1dd6061fa6
|
||||
MxQXhL/origin/1/0: 69d8634b177fdf937764b406fd477547
|
||||
MxQXhL/translation: c1c949477e121d73ed6683eddf9cd874
|
||||
WHHLh9/message: 99d0b17b78d44e15f13d876d155f0efc
|
||||
WHHLh9/origin/0/0: 3a89a46ac678e34dc8eb687b07a4ad4b
|
||||
@@ -2399,6 +2526,12 @@ checksums:
|
||||
2QGEbi/message: 550198b2c87f06726a843c79c1026ed9
|
||||
2QGEbi/origin/0/0: 4b4f55c033add8db69178563832227c6
|
||||
2QGEbi/translation: 550198b2c87f06726a843c79c1026ed9
|
||||
Oo4E6p/message: af985cf72c47df76e2f2139a427d9948
|
||||
Oo4E6p/origin/0/0: 97bd206a05414e2a571020d64e166093
|
||||
Oo4E6p/translation: af985cf72c47df76e2f2139a427d9948
|
||||
K7k9u3/message: 1cf9d227042f6a65adba38cb7296830d
|
||||
K7k9u3/origin/0/0: fd0e66cef8d46e96bcf3143a12f9b6db
|
||||
K7k9u3/translation: 1cf9d227042f6a65adba38cb7296830d
|
||||
8yFGGF/message: 39025a0c53818438829603d213baef06
|
||||
8yFGGF/origin/0/0: 68450df287fb46ea629e818732c1291a
|
||||
8yFGGF/translation: 39025a0c53818438829603d213baef06
|
||||
@@ -2411,6 +2544,9 @@ checksums:
|
||||
A8jqN7/message: 656c93265d7e2bef1245b17d85f85ae5
|
||||
A8jqN7/origin/0/0: 1fd8ccf586705354bcae6e1186108fc7
|
||||
A8jqN7/translation: 656c93265d7e2bef1245b17d85f85ae5
|
||||
Q60WUZ/translation: 4284c33aed2f2c5e004ed0a7d7d9bf87
|
||||
Q60WUZ/message: 4284c33aed2f2c5e004ed0a7d7d9bf87
|
||||
Q60WUZ/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
T7Mywq/message: 62899897d7bffcb1df3af77d460f0881
|
||||
T7Mywq/origin/0/0: 0ad2af981579a62b084b3d41462c5546
|
||||
T7Mywq/translation: 62899897d7bffcb1df3af77d460f0881
|
||||
@@ -2503,6 +2639,9 @@ checksums:
|
||||
mx8%2B1u/origin/3/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
mx8%2B1u/origin/4/0: dbad0c8d7863cb41f5495264f82e7081
|
||||
mx8%2B1u/translation: f2949ca2dc18b0063af92e60779abb65
|
||||
8AwlaR/translation: acb1fdc14ed875815ae9f8a5254bc634
|
||||
8AwlaR/message: acb1fdc14ed875815ae9f8a5254bc634
|
||||
8AwlaR/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
Ws%2B3X%2B/message: 905b10eeb09fdc5ac7fc757e935ee757
|
||||
Ws%2B3X%2B/origin/0/0: fadd5a5b6963ec5f261072f7e8d2140b
|
||||
Ws%2B3X%2B/translation: 905b10eeb09fdc5ac7fc757e935ee757
|
||||
@@ -2543,6 +2682,7 @@ checksums:
|
||||
IelE1h/translation: 972773025e763ddf53273df6d37a729a
|
||||
cWtfn1/message: 9a91ea70f5eb55aac96640bf0fd7feff
|
||||
cWtfn1/origin/0/0: ff4a160eca5f8da4f075fd1dd6061fa6
|
||||
cWtfn1/origin/1/0: 69d8634b177fdf937764b406fd477547
|
||||
cWtfn1/translation: 9a91ea70f5eb55aac96640bf0fd7feff
|
||||
b3Thhd/message: 5b7b755f05330164dbfb00096c500ee3
|
||||
b3Thhd/origin/0/0: 12c1fab543c8848bcb10107d47336736
|
||||
@@ -2674,7 +2814,8 @@ checksums:
|
||||
UlhdTP/origin/0/0: 83911e3eacbad4583e2b1647a784d154
|
||||
UlhdTP/translation: bc5c267ce3f04de94ff1379cf2ca48a3
|
||||
chyf4J/message: 7159d620b7ef5c5afef734989a5be08b
|
||||
chyf4J/origin/0/0: 5f6c4a0c9be5098099167871ae1564af
|
||||
chyf4J/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
chyf4J/origin/1/0: 5f6c4a0c9be5098099167871ae1564af
|
||||
chyf4J/translation: 7159d620b7ef5c5afef734989a5be08b
|
||||
Ax%2FhYa/message: d0e83b9a0304d7c36cf8c85d98783ce2
|
||||
Ax%2FhYa/origin/0/0: 33bf266228f835e12c0bfb0e5efb3be9
|
||||
@@ -2692,7 +2833,8 @@ checksums:
|
||||
wtxjAY/translation: 1857292f9567c556c781a23bd7e10544
|
||||
CozWO1/message: 855614bbf862fd6a9f6a3e76943f92d4
|
||||
CozWO1/origin/0/0: ff4a160eca5f8da4f075fd1dd6061fa6
|
||||
CozWO1/origin/1/0: 5f6c4a0c9be5098099167871ae1564af
|
||||
CozWO1/origin/1/0: 69d8634b177fdf937764b406fd477547
|
||||
CozWO1/origin/2/0: 5f6c4a0c9be5098099167871ae1564af
|
||||
CozWO1/translation: 855614bbf862fd6a9f6a3e76943f92d4
|
||||
ghSJ4U/message: 681f86c9ca31699fc5a3ca3790e5972c
|
||||
ghSJ4U/origin/0/0: ff4a160eca5f8da4f075fd1dd6061fa6
|
||||
@@ -2735,6 +2877,9 @@ checksums:
|
||||
RtlIYB/message: df4783d593505766d78c5bc08d3d48ac
|
||||
RtlIYB/origin/0/0: 627b72cd19a7154ae1c28cbd7ca0c730
|
||||
RtlIYB/translation: df4783d593505766d78c5bc08d3d48ac
|
||||
3WXdoZ/translation: 4cbeab40f77975492a23eec428732440
|
||||
3WXdoZ/message: 4cbeab40f77975492a23eec428732440
|
||||
3WXdoZ/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
aelko%2B/message: 41dd145ef56f539e12dc064a9807c660
|
||||
aelko%2B/origin/0/0: 4980d8e27a628e7cd9a70b839d844083
|
||||
aelko%2B/translation: 41dd145ef56f539e12dc064a9807c660
|
||||
@@ -2778,6 +2923,9 @@ checksums:
|
||||
GoDLB9/message: 8c8d944e07388c5877effdb2c2803dcf
|
||||
GoDLB9/origin/0/0: 5c60161e173f5eae9276d8e4c70b4ebb
|
||||
GoDLB9/translation: 8c8d944e07388c5877effdb2c2803dcf
|
||||
c4nMcR/translation: bf4f697079eef51c3ebe46ce79063895
|
||||
c4nMcR/message: bf4f697079eef51c3ebe46ce79063895
|
||||
c4nMcR/origin/0/0: 15ea2dfd5eae4e05b226b1320103476e
|
||||
evg7%2BA/message: 403972e7a25afc2415762c1c2b1ec868
|
||||
evg7%2BA/origin/0/0: 3c57a918258af4b44c187f58d203345f
|
||||
evg7%2BA/translation: 403972e7a25afc2415762c1c2b1ec868
|
||||
@@ -2814,6 +2962,12 @@ checksums:
|
||||
25fAUC/message: 3e4cce96bc1197a1caa2b7fb4d3c7e53
|
||||
25fAUC/origin/0/0: d1e1d7ccce60e05570bedfbb93fc9416
|
||||
25fAUC/translation: 3e4cce96bc1197a1caa2b7fb4d3c7e53
|
||||
GRAGsB/translation: 751a534fd6e62a92ff64c46894c7db86
|
||||
GRAGsB/message: 751a534fd6e62a92ff64c46894c7db86
|
||||
GRAGsB/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
j0o6ml/translation: 1e036ffca9d9cb9e2941b83fbbf375c0
|
||||
j0o6ml/message: 1e036ffca9d9cb9e2941b83fbbf375c0
|
||||
j0o6ml/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
GnSSGm/message: 98de6f65c567c6654cc0adce3c9d5656
|
||||
GnSSGm/origin/0/0: 33bf266228f835e12c0bfb0e5efb3be9
|
||||
GnSSGm/translation: 98de6f65c567c6654cc0adce3c9d5656
|
||||
@@ -2826,6 +2980,10 @@ checksums:
|
||||
Hg1qE9/message: c808949b9b2b4a9aba2472f5d1050167
|
||||
Hg1qE9/origin/0/0: 30791e26a172d47d3cb0693e82679246
|
||||
Hg1qE9/translation: c808949b9b2b4a9aba2472f5d1050167
|
||||
OTxjpR/translation: 370a32c49489db61978ac91b55699c24
|
||||
OTxjpR/message: 370a32c49489db61978ac91b55699c24
|
||||
OTxjpR/origin/0/0: 69d8634b177fdf937764b406fd477547
|
||||
OTxjpR/origin/1/0: 69d8634b177fdf937764b406fd477547
|
||||
4DOCMI/message: 0b48896061a1124501fdaba026804148
|
||||
4DOCMI/origin/0/0: a50c4fbde8da6e0a77c4e0aef0b44dea
|
||||
4DOCMI/translation: 0b48896061a1124501fdaba026804148
|
||||
|
||||
@@ -28,6 +28,7 @@ const config = {
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
/** Enables hot reloading for local packages without a build step */
|
||||
transpilePackages: [
|
||||
"@kan/api",
|
||||
@@ -65,6 +66,8 @@ const config = {
|
||||
},
|
||||
},
|
||||
},
|
||||
serverExternalPackages: ["pino"],
|
||||
|
||||
experimental: {
|
||||
// instrumentationHook: true,
|
||||
swcPlugins: [["@lingui/swc-plugin", {}]],
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useTheme } from "next-themes";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { env } from "next-runtime-env";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
TbLayoutSidebarLeftCollapse,
|
||||
@@ -43,6 +45,7 @@ export default function Dashboard({
|
||||
const { resolvedTheme } = useTheme();
|
||||
const { openModal } = useModal();
|
||||
const { availableWorkspaces, hasLoaded } = useWorkspace();
|
||||
const router = useRouter();
|
||||
|
||||
const { data: session, isPending: sessionLoading } = authClient.useSession();
|
||||
const { data: user, isLoading: userLoading } = api.user.getUser.useQuery(
|
||||
@@ -98,9 +101,13 @@ export default function Dashboard({
|
||||
|
||||
useEffect(() => {
|
||||
if (hasLoaded && availableWorkspaces.length === 0) {
|
||||
openModal("NEW_WORKSPACE", undefined, undefined, false);
|
||||
if (env("NEXT_PUBLIC_KAN_ENV") === "cloud") {
|
||||
router.push(`/onboarding/select-plan?returnUrl=${encodeURIComponent(window.location.pathname)}`);
|
||||
} else {
|
||||
openModal("NEW_WORKSPACE", undefined, undefined, false);
|
||||
}
|
||||
}
|
||||
}, [hasLoaded, availableWorkspaces.length, openModal]);
|
||||
}, [hasLoaded, availableWorkspaces.length, openModal, router]);
|
||||
|
||||
const isDarkMode = resolvedTheme === "dark";
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||
</button>
|
||||
)}
|
||||
{iconRight && type !== "password" && (
|
||||
<div className="absolute right-3 top-1/2 -translate-y-1/2">
|
||||
<div className="absolute right-3 top-1/2 -translate-y-1/2 leading-[0]">
|
||||
{iconRight}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -39,7 +39,7 @@ export function LabelForm({
|
||||
labelPublicId: entityId,
|
||||
},
|
||||
{
|
||||
enabled: isEdit && !!entityId,
|
||||
enabled: !!isEdit && entityId.length >= 12,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -207,7 +207,7 @@ export function LabelForm({
|
||||
/>
|
||||
</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">
|
||||
<div className="mt-12 flex items-center justify-end space-x-4 border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
{!isEdit && (
|
||||
<Toggle
|
||||
label={t`Create another`}
|
||||
|
||||
@@ -114,42 +114,6 @@ export function NewWorkspaceForm() {
|
||||
weekStartDay: 1,
|
||||
});
|
||||
|
||||
// If in cloud and Pro toggle is enabled, create checkout session for pro
|
||||
if (env("NEXT_PUBLIC_KAN_ENV") === "cloud" && isProToggleEnabled) {
|
||||
try {
|
||||
const response = await fetch(
|
||||
"/api/stripe/create_checkout_session",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
slug: slug || undefined,
|
||||
workspacePublicId: values.publicId,
|
||||
cancelUrl: "/settings/workspace?upgrade=pro",
|
||||
successUrl: "/boards",
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
const url = (data as { url: string }).url;
|
||||
|
||||
if (url) {
|
||||
window.location.href = url;
|
||||
return; // Don't close modal if redirecting to checkout
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error creating checkout session:", error);
|
||||
showPopup({
|
||||
header: t`Error upgrading to Pro`,
|
||||
message: t`Workspace created successfully. You can upgrade later in settings.`,
|
||||
icon: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
closeModal();
|
||||
}
|
||||
},
|
||||
@@ -361,7 +325,7 @@ export function NewWorkspaceForm() {
|
||||
</div>
|
||||
<div
|
||||
className={twMerge(
|
||||
"mt-6 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600",
|
||||
"mt-6 flex items-center justify-end space-x-4 border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600",
|
||||
!showProBenefits && "mt-12",
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -7,15 +7,17 @@ const Toggle = ({
|
||||
label,
|
||||
disabled,
|
||||
showLabel = true,
|
||||
labelPosition = "before",
|
||||
}: {
|
||||
isChecked: boolean;
|
||||
onChange: () => void;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
showLabel?: boolean;
|
||||
labelPosition?: "before" | "after";
|
||||
}) => (
|
||||
<div className="mr-4 flex items-center justify-end">
|
||||
{showLabel && (
|
||||
<div className="flex items-center">
|
||||
{showLabel && labelPosition === "before" && (
|
||||
<span className="mr-2 text-xs text-light-900 dark:text-dark-900">
|
||||
{label}
|
||||
</span>
|
||||
@@ -38,6 +40,11 @@ const Toggle = ({
|
||||
)}
|
||||
/>
|
||||
</Switch>
|
||||
{showLabel && labelPosition === "after" && (
|
||||
<span className="ml-2 text-xs text-light-900 dark:text-dark-900">
|
||||
{label}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Button, Menu, Transition } from "@headlessui/react";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { env } from "next-runtime-env";
|
||||
import { Fragment, useState } from "react";
|
||||
import { HiCheck, HiMagnifyingGlass } from "react-icons/hi2";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
@@ -18,6 +20,7 @@ export default function WorkspaceMenu({
|
||||
const { workspace, isLoading, availableWorkspaces, switchWorkspace } =
|
||||
useWorkspace();
|
||||
const { openModal } = useModal();
|
||||
const router = useRouter();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const { tooltipContent: commandPaletteShortcutTooltipContent } =
|
||||
@@ -147,7 +150,11 @@ export default function WorkspaceMenu({
|
||||
<div className="border-t-[1px] border-light-600 p-1 dark:border-dark-500">
|
||||
<Menu.Item>
|
||||
<button
|
||||
onClick={() => openModal("NEW_WORKSPACE")}
|
||||
onClick={() =>
|
||||
env("NEXT_PUBLIC_KAN_ENV") === "cloud"
|
||||
? router.push(`/onboarding/select-plan?returnUrl=${encodeURIComponent(window.location.pathname)}`)
|
||||
: openModal("NEW_WORKSPACE")
|
||||
}
|
||||
className="flex w-full items-center justify-between rounded-[5px] px-3 py-2 text-left text-xs text-neutral-900 hover:bg-light-200 dark:text-dark-1000 dark:hover:bg-dark-400"
|
||||
>
|
||||
{t`Create workspace`}
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
"0": ["isTemplate ? \"Template\" : \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 440]],
|
||||
"origin": [["src/views/board/index.tsx", 556]],
|
||||
"translation": "{0} nicht gefunden"
|
||||
},
|
||||
"0xWkkH": {
|
||||
@@ -238,6 +238,13 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 110]],
|
||||
"translation": "Aktivitätsprotokolle"
|
||||
},
|
||||
"UGCIzB": {
|
||||
"message": "Add / edit label",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 50]],
|
||||
"translation": "Label hinzufügen / bearbeiten"
|
||||
},
|
||||
"B3xxao": {
|
||||
"message": "Add a card",
|
||||
"placeholders": {},
|
||||
@@ -288,8 +295,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/LabelSelector.tsx", 113],
|
||||
["src/views/card/components/LabelSelector.tsx", 118]
|
||||
["src/views/card/components/LabelSelector.tsx", 114],
|
||||
["src/views/card/components/LabelSelector.tsx", 119]
|
||||
],
|
||||
"translation": "Label hinzufügen"
|
||||
},
|
||||
@@ -298,7 +305,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 134],
|
||||
["src/views/card/components/MemberSelector.tsx", 135],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 257]
|
||||
],
|
||||
"translation": "Mitglied hinzufügen"
|
||||
@@ -549,6 +556,13 @@
|
||||
],
|
||||
"translation": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
},
|
||||
"YkfDoz": {
|
||||
"translation": "Jährlich",
|
||||
"message": "Annual",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 63]]
|
||||
},
|
||||
"3bqt9U": {
|
||||
"message": "Anyone with this link can join your workspace",
|
||||
"placeholders": {},
|
||||
@@ -749,6 +763,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 59]],
|
||||
"translation": "Wartet auf Kunden"
|
||||
},
|
||||
"iH8pgl": {
|
||||
"translation": "Zurück",
|
||||
"message": "Back",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 275]]
|
||||
},
|
||||
"KNKCTb": {
|
||||
"message": "Backlog",
|
||||
"placeholders": {},
|
||||
@@ -791,6 +812,13 @@
|
||||
"origin": [["src/views/pricing/components/PricingTiers.tsx", 53]],
|
||||
"translation": "Ideal für kleine und wachsende Teams, die zusammenarbeiten müssen"
|
||||
},
|
||||
"zt/6cS": {
|
||||
"translation": "Ideal für kleine Teams, die gemeinsam arbeiten und schneller vorankommen möchten.",
|
||||
"message": "Best for small teams who want to collaborate and move faster together.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 86]]
|
||||
},
|
||||
"qaS+1/": {
|
||||
"message": "Best for teams that want to scale without limits",
|
||||
"placeholders": {},
|
||||
@@ -842,7 +870,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/card/index.tsx", 317],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
@@ -1235,12 +1263,14 @@
|
||||
"origin": [
|
||||
["src/components/DeleteLabelConfirmation.tsx", 49],
|
||||
["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 176],
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 267],
|
||||
["src/views/board/components/DeleteBoardConfirmation.tsx", 44],
|
||||
["src/views/card/components/Comment.tsx", 195],
|
||||
["src/views/card/components/DeleteCardConfirmation.tsx", 86],
|
||||
["src/views/card/components/DeleteChecklistConfirmation.tsx", 64],
|
||||
["src/views/card/components/DeleteCommentConfirmation.tsx", 77],
|
||||
["src/views/members/components/DeleteMemberConfirmation.tsx", 55],
|
||||
["src/views/onboarding/select-plan/index.tsx", 209],
|
||||
["src/views/settings/components/Avatar.tsx", 287],
|
||||
["src/views/settings/components/ChangePasswordConfirmation.tsx", 168],
|
||||
[
|
||||
@@ -1261,6 +1291,15 @@
|
||||
"origin": [["src/views/card/index.tsx", 317]],
|
||||
"translation": "Karte"
|
||||
},
|
||||
"sU2uWc": {
|
||||
"message": "Card duplicated",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 67]
|
||||
],
|
||||
"translation": "Karte dupliziert"
|
||||
},
|
||||
"fEY2vP": {
|
||||
"message": "Card not found",
|
||||
"placeholders": {},
|
||||
@@ -1283,6 +1322,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 307],
|
||||
["src/views/card/components/Dropdown.tsx", 44],
|
||||
["src/views/public/board/CardModal.tsx", 38]
|
||||
],
|
||||
@@ -1360,6 +1400,13 @@
|
||||
],
|
||||
"translation": "Checklisten"
|
||||
},
|
||||
"zMquA7": {
|
||||
"translation": "Tarif wählen",
|
||||
"message": "Choose a plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 122]]
|
||||
},
|
||||
"VHS0aJ": {
|
||||
"message": "Clear all custom permissions?",
|
||||
"placeholders": {},
|
||||
@@ -1617,6 +1664,16 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 40]],
|
||||
"translation": "Content-Erstellung"
|
||||
},
|
||||
"xGVfLh": {
|
||||
"translation": "Weiter",
|
||||
"message": "Continue",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 212],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 291]
|
||||
]
|
||||
},
|
||||
"J2Wbjt": {
|
||||
"message": "Continue with ",
|
||||
"placeholders": {},
|
||||
@@ -1661,6 +1718,40 @@
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 58]],
|
||||
"translation": "Karten-Link kopieren"
|
||||
},
|
||||
"0utuU6": {
|
||||
"message": "Copy checklists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 257]
|
||||
],
|
||||
"translation": "Checklisten kopieren"
|
||||
},
|
||||
"fDQ7hA": {
|
||||
"message": "Copy labels",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 221]
|
||||
],
|
||||
"translation": "Labels kopieren"
|
||||
},
|
||||
"1bJKhj": {
|
||||
"message": "Copy link to card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 62]],
|
||||
"translation": "Link zur Karte kopieren"
|
||||
},
|
||||
"uvH2xS": {
|
||||
"message": "Copy members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 239]
|
||||
],
|
||||
"translation": "Mitglieder kopieren"
|
||||
},
|
||||
"9PaIxv": {
|
||||
"message": "Core features",
|
||||
"placeholders": {},
|
||||
@@ -1757,7 +1848,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewCardForm.tsx", 417],
|
||||
["src/views/card/components/LabelSelector.tsx", 100]
|
||||
["src/views/card/components/LabelSelector.tsx", 101]
|
||||
],
|
||||
"translation": "Neues Label erstellen"
|
||||
},
|
||||
@@ -1766,8 +1857,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 76],
|
||||
["src/views/board/index.tsx", 554]
|
||||
["src/views/board/index.tsx", 91],
|
||||
["src/views/board/index.tsx", 670]
|
||||
],
|
||||
"translation": "Neue Liste erstellen"
|
||||
},
|
||||
@@ -1791,7 +1882,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 388],
|
||||
["src/components/WorkspaceMenu.tsx", 153]
|
||||
["src/components/WorkspaceMenu.tsx", 160]
|
||||
],
|
||||
"translation": "Workspace erstellen"
|
||||
},
|
||||
@@ -1891,6 +1982,13 @@
|
||||
],
|
||||
"translation": "Benutzerdefinierter Benutzername"
|
||||
},
|
||||
"ZDPJBc": {
|
||||
"translation": "Benutzerdefinierte Benutzernamen erfordern ein Upgrade auf einen Pro-Tarif",
|
||||
"message": "Custom usernames require upgrading to a Pro plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 220]]
|
||||
},
|
||||
"j9IZZ0": {
|
||||
"message": "Custom workspace URL",
|
||||
"placeholders": {},
|
||||
@@ -1985,7 +2083,10 @@
|
||||
"message": "Delete card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 76]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMenu.tsx", 74],
|
||||
["src/views/card/components/Dropdown.tsx", 76]
|
||||
],
|
||||
"translation": "Karte löschen"
|
||||
},
|
||||
"njJFtc": {
|
||||
@@ -2171,6 +2272,9 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 36],
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 48],
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 68],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 17],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 23],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 29],
|
||||
@@ -2226,6 +2330,34 @@
|
||||
"origin": [["src/views/board/components/Filters.tsx", 122]],
|
||||
"translation": "Morgen fällig"
|
||||
},
|
||||
"euc6Ns": {
|
||||
"message": "Duplicate",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplizieren"
|
||||
},
|
||||
"BTDPLo": {
|
||||
"message": "Duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 111],
|
||||
["src/views/board/components/CardContextMenu.tsx", 68]
|
||||
],
|
||||
"translation": "Karte duplizieren"
|
||||
},
|
||||
"06EQqT": {
|
||||
"message": "Duplicating…",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Wird dupliziert…"
|
||||
},
|
||||
"ePK91l": {
|
||||
"message": "Edit",
|
||||
"placeholders": {},
|
||||
@@ -2338,6 +2470,22 @@
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 100]],
|
||||
"translation": "E-Mail-Sichtbarkeit"
|
||||
},
|
||||
"bFREhu": {
|
||||
"message": "End of list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 200]
|
||||
],
|
||||
"translation": "Ende der Liste"
|
||||
},
|
||||
"SUXBxp": {
|
||||
"translation": "Technik",
|
||||
"message": "Engineering",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"0+ewPp": {
|
||||
"message": "Enhancement",
|
||||
"placeholders": {},
|
||||
@@ -2794,6 +2942,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 77],
|
||||
["src/views/onboarding/select-plan/index.tsx", 78],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 331],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
@@ -2894,7 +3044,7 @@
|
||||
"message": "Get started by creating a new list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 539]],
|
||||
"origin": [["src/views/board/index.tsx", 655]],
|
||||
"translation": "Legen Sie los, indem Sie eine neue Liste erstellen"
|
||||
},
|
||||
"oW13KZ": {
|
||||
@@ -3004,6 +3154,13 @@
|
||||
"origin": [["src/components/SideNavigation.tsx", 119]],
|
||||
"translation": "Zu Vorlagen gehen"
|
||||
},
|
||||
"SUvm1Y": {
|
||||
"translation": "Gut geeignet für Einsteiger, die nur die wichtigsten Funktionen benötigen.",
|
||||
"message": "Good for individuals starting out who just need the essentials.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 79]]
|
||||
},
|
||||
"cdyS7J": {
|
||||
"message": "Google SSO",
|
||||
"placeholders": {},
|
||||
@@ -3314,7 +3471,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 114],
|
||||
["src/views/card/components/MemberSelector.tsx", 115],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 367]
|
||||
],
|
||||
"translation": "Mitglied einladen"
|
||||
@@ -3386,6 +3543,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 31],
|
||||
["src/views/board/components/Filters.tsx", 155],
|
||||
["src/views/board/components/NewCardForm.tsx", 421],
|
||||
["src/views/card/index.tsx", 133]
|
||||
@@ -3497,6 +3655,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 80],
|
||||
["src/views/board/index.tsx", 305],
|
||||
["src/views/card/components/Dropdown.tsx", 42],
|
||||
["src/views/public/board/CardModal.tsx", 36],
|
||||
["src/views/public/board/index.tsx", 77]
|
||||
@@ -3507,7 +3666,10 @@
|
||||
"message": "List",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 124]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 117],
|
||||
["src/views/card/index.tsx", 124]
|
||||
],
|
||||
"translation": "Liste"
|
||||
},
|
||||
"zQX5Dj": {
|
||||
@@ -3596,6 +3758,16 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Vorlage erstellen"
|
||||
},
|
||||
"hB02vO": {
|
||||
"message": "Manage members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 51],
|
||||
["src/views/board/components/CardContextMenu.tsx", 38]
|
||||
],
|
||||
"translation": "Mitglieder verwalten"
|
||||
},
|
||||
"IDvohQ": {
|
||||
"message": "marked a checklist item as incomplete",
|
||||
"placeholders": {},
|
||||
@@ -3612,6 +3784,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 258]],
|
||||
"translation": "hat Checklistenelement <0>{0}</0> als unvollständig markiert"
|
||||
},
|
||||
"vo2a+a": {
|
||||
"translation": "Marketing",
|
||||
"message": "Marketing",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"agPptk": {
|
||||
"message": "Medium",
|
||||
"placeholders": {},
|
||||
@@ -3683,6 +3862,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 62],
|
||||
["src/views/pricing/components/Pricing.tsx", 14],
|
||||
["src/views/pricing/index.tsx", 20]
|
||||
],
|
||||
@@ -3695,6 +3875,20 @@
|
||||
"origin": [["src/views/members/components/InviteMemberForm.tsx", 159]],
|
||||
"translation": "Monatliche Abrechnung"
|
||||
},
|
||||
"51UCsN": {
|
||||
"message": "Move to another list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 44]],
|
||||
"translation": "In andere Liste verschieben"
|
||||
},
|
||||
"J4+OTA": {
|
||||
"message": "Move to list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 70]],
|
||||
"translation": "In Liste verschieben"
|
||||
},
|
||||
"BOqTi5": {
|
||||
"message": "moved the card from <0>{0}</0> to<1>{1}</1>",
|
||||
"placeholders": {
|
||||
@@ -3806,7 +4000,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewListForm.tsx", 113],
|
||||
["src/views/board/index.tsx", 503]
|
||||
["src/views/board/index.tsx", 619]
|
||||
],
|
||||
"translation": "Neue Liste"
|
||||
},
|
||||
@@ -3932,14 +4126,14 @@
|
||||
"message": "No lists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 535]],
|
||||
"origin": [["src/views/board/index.tsx", 651]],
|
||||
"translation": "Keine Listen"
|
||||
},
|
||||
"fvLNDy": {
|
||||
"message": "No lists have been created yet",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 540]],
|
||||
"origin": [["src/views/board/index.tsx", 656]],
|
||||
"translation": "Es wurden noch keine Listen erstellt"
|
||||
},
|
||||
"i30J2U": {
|
||||
@@ -4020,7 +4214,7 @@
|
||||
"message": "Open command menu",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 31]],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 34]],
|
||||
"translation": "Befehlsmenü öffnen"
|
||||
},
|
||||
"cFQEU/": {
|
||||
@@ -4236,6 +4430,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 86]],
|
||||
"translation": "Persönliches Projekt"
|
||||
},
|
||||
"Oi+J+N": {
|
||||
"translation": "Wählen Sie einen Tarif, um loszulegen. Alle kostenpflichtigen Tarife beinhalten eine 14-tägige kostenlose Testphase.",
|
||||
"message": "Pick a plan to get started. All paid plans include a 14-day free trial.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 125]]
|
||||
},
|
||||
"Iqh0Uv": {
|
||||
"message": "Planned",
|
||||
"placeholders": {},
|
||||
@@ -4331,8 +4532,8 @@
|
||||
["src/views/board/components/NewTemplateForm.tsx", 77],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 73],
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 194],
|
||||
["src/views/board/index.tsx", 250],
|
||||
["src/views/board/index.tsx", 217],
|
||||
["src/views/board/index.tsx", 273],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
@@ -4360,6 +4561,8 @@
|
||||
["src/views/members/components/InviteMemberForm.tsx", 104],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 241],
|
||||
["src/views/members/index.tsx", 66],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 101],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 150],
|
||||
["src/views/settings/components/Avatar.tsx", 200],
|
||||
["src/views/settings/components/DeleteAccountConfirmation.tsx", 40],
|
||||
["src/views/settings/components/DeleteWorkspaceConfirmation.tsx", 46],
|
||||
@@ -4387,12 +4590,24 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 76],
|
||||
["src/views/board/components/CardContextMoveListModal.tsx", 42],
|
||||
["src/views/board/index.tsx", 314],
|
||||
["src/views/card/components/Dropdown.tsx", 51],
|
||||
["src/views/public/board/CardModal.tsx", 45],
|
||||
["src/views/public/board/index.tsx", 86]
|
||||
],
|
||||
"translation": "Bitte versuchen Sie es erneut."
|
||||
},
|
||||
"nYNMZZ": {
|
||||
"message": "Position in list (0 = first, leave empty for end)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 193]
|
||||
],
|
||||
"translation": "Position in Liste (0 = erste, leer lassen für Ende)"
|
||||
},
|
||||
"aHCEmh": {
|
||||
"message": "Pricing",
|
||||
"placeholders": {},
|
||||
@@ -4438,6 +4653,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 91],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 333],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 70]
|
||||
],
|
||||
@@ -4695,7 +4911,8 @@
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 36],
|
||||
["src/views/home/components/Header.tsx", 13],
|
||||
["src/views/home/components/Header.tsx", 28]
|
||||
["src/views/home/components/Header.tsx", 28],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 161]
|
||||
],
|
||||
"translation": "Roadmap"
|
||||
},
|
||||
@@ -4814,6 +5031,15 @@
|
||||
"origin": [["src/views/home/components/Testimonials.tsx", 239]],
|
||||
"translation": "Sehen Sie, was unsere Nutzer über Kan sagen"
|
||||
},
|
||||
"zYRVNp": {
|
||||
"message": "Select a list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 131]
|
||||
],
|
||||
"translation": "Liste auswählen"
|
||||
},
|
||||
"wgNoIs": {
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
@@ -4884,7 +5110,11 @@
|
||||
"message": "Set due date",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/DueDateSelector.tsx", 121]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 20],
|
||||
["src/views/board/components/CardContextMenu.tsx", 56],
|
||||
["src/views/card/components/DueDateSelector.tsx", 121]
|
||||
],
|
||||
"translation": "Fälligkeitsdatum festlegen"
|
||||
},
|
||||
"Eit43O": {
|
||||
@@ -4894,6 +5124,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 142]],
|
||||
"translation": "hat das Fälligkeitsdatum festgelegt"
|
||||
},
|
||||
"JjEJSy": {
|
||||
"translation": "Richten Sie Ihren Workspace ein",
|
||||
"message": "Set up your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 179]]
|
||||
},
|
||||
"Tz0i8g": {
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
@@ -4974,6 +5211,16 @@
|
||||
"origin": [["src/views/invite/index.tsx", 154]],
|
||||
"translation": "Anmelden"
|
||||
},
|
||||
"fcWrnU": {
|
||||
"translation": "Abmelden",
|
||||
"message": "Sign out",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 284],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 362]
|
||||
]
|
||||
},
|
||||
"mErq7F": {
|
||||
"message": "Sign Up",
|
||||
"placeholders": {},
|
||||
@@ -5059,6 +5306,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 22]],
|
||||
"translation": "Softwareentwicklung"
|
||||
},
|
||||
"6sKjjx": {
|
||||
"translation": "Solo",
|
||||
"message": "Solo",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 76]]
|
||||
},
|
||||
"vnS6Rf": {
|
||||
"message": "SSO",
|
||||
"placeholders": {},
|
||||
@@ -5158,6 +5412,13 @@
|
||||
"origin": [["src/components/UserMenu.tsx", 144]],
|
||||
"translation": "System"
|
||||
},
|
||||
"KM6m8p": {
|
||||
"translation": "Team",
|
||||
"message": "Team",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 83]]
|
||||
},
|
||||
"bff61F": {
|
||||
"message": "Team Plan",
|
||||
"placeholders": {},
|
||||
@@ -5184,8 +5445,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 449]
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/board/index.tsx", 565]
|
||||
],
|
||||
"translation": "Vorlage"
|
||||
},
|
||||
@@ -5279,6 +5540,15 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Das Board wurde wiederhergestellt."
|
||||
},
|
||||
"nKBUeF": {
|
||||
"message": "The card has been duplicated.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 69]
|
||||
],
|
||||
"translation": "Die Karte wurde dupliziert."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5401,6 +5671,20 @@
|
||||
],
|
||||
"translation": "Die Berechtigungen dieses Mitglieds wurden auf die Standardwerte seiner Rolle zurückgesetzt."
|
||||
},
|
||||
"HQVm6e": {
|
||||
"translation": "Diese URL ist bereits vergeben",
|
||||
"message": "This URL has already been taken",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 73]]
|
||||
},
|
||||
"gKmoow": {
|
||||
"translation": "Diese URL ist reserviert",
|
||||
"message": "This URL is reserved",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 75]]
|
||||
},
|
||||
"OAYToL": {
|
||||
"message": "This will remove all custom member permissions in this workspace. Members will inherit permissions only from their roles.",
|
||||
"placeholders": {},
|
||||
@@ -5461,6 +5745,15 @@
|
||||
"origin": [["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 127]],
|
||||
"translation": "Titel"
|
||||
},
|
||||
"wK4OTM": {
|
||||
"message": "Title (optional)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 180]
|
||||
],
|
||||
"translation": "Titel (optional)"
|
||||
},
|
||||
"Se/UIp": {
|
||||
"message": "To Do",
|
||||
"placeholders": {},
|
||||
@@ -5563,6 +5856,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 312],
|
||||
["src/views/card/components/Dropdown.tsx", 49],
|
||||
["src/views/public/board/CardModal.tsx", 43],
|
||||
["src/views/public/board/index.tsx", 84]
|
||||
@@ -5604,7 +5898,10 @@
|
||||
"message": "Unable to create workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 158]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 100]
|
||||
],
|
||||
"translation": "Workspace konnte nicht erstellt werden"
|
||||
},
|
||||
"WHHLh9": {
|
||||
@@ -5644,6 +5941,22 @@
|
||||
"origin": [["src/views/card/components/DeleteCommentConfirmation.tsx", 45]],
|
||||
"translation": "Kommentar konnte nicht gelöscht werden"
|
||||
},
|
||||
"Oo4E6p": {
|
||||
"message": "Unable to duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 75]
|
||||
],
|
||||
"translation": "Karte konnte nicht dupliziert werden"
|
||||
},
|
||||
"K7k9u3": {
|
||||
"message": "Unable to move card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 41]],
|
||||
"translation": "Karte konnte nicht verschoben werden"
|
||||
},
|
||||
"8yFGGF": {
|
||||
"message": "Unable to remove member",
|
||||
"placeholders": {},
|
||||
@@ -5676,6 +5989,13 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 40]],
|
||||
"translation": "Feedback konnte nicht gesendet werden"
|
||||
},
|
||||
"Q60WUZ": {
|
||||
"translation": "Checkout kann nicht gestartet werden",
|
||||
"message": "Unable to start checkout",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 149]]
|
||||
},
|
||||
"T7Mywq": {
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
@@ -5702,7 +6022,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 249],
|
||||
["src/views/board/index.tsx", 272],
|
||||
["src/views/card/index.tsx", 231]
|
||||
],
|
||||
"translation": "Karte konnte nicht aktualisiert werden"
|
||||
@@ -5747,7 +6067,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 193],
|
||||
["src/views/board/index.tsx", 216],
|
||||
["src/views/card/components/ListSelector.tsx", 54]
|
||||
],
|
||||
"translation": "Liste konnte nicht aktualisiert werden"
|
||||
@@ -5883,6 +6203,13 @@
|
||||
],
|
||||
"translation": "Unbegrenzte Mitglieder"
|
||||
},
|
||||
"8AwlaR": {
|
||||
"translation": "Unbegrenzte Mitglieder und ein individueller Workspace-Benutzername für Teams, die wachsen möchten.",
|
||||
"message": "Unlimited members and a custom workspace username for teams ready to scale.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 94]]
|
||||
},
|
||||
"Ws+3X+": {
|
||||
"message": "Unlimited seats and advanced features for growing teams.",
|
||||
"placeholders": {},
|
||||
@@ -5972,7 +6299,10 @@
|
||||
"message": "Upgrade to Pro ($29/month)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 373]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 373],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 243]
|
||||
],
|
||||
"translation": "Auf Pro upgraden (29 $/Monat)"
|
||||
},
|
||||
"b3Thhd": {
|
||||
@@ -6256,7 +6586,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 47],
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
@@ -6284,7 +6614,10 @@
|
||||
"message": "Workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 82]],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 253],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 82]
|
||||
],
|
||||
"translation": "Workspace-Beschreibung"
|
||||
},
|
||||
"Ax/hYa": {
|
||||
@@ -6331,6 +6664,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 263],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 188],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 63]
|
||||
],
|
||||
"translation": "Workspace-Name"
|
||||
@@ -6438,6 +6772,13 @@
|
||||
"origin": [["src/views/settings/AccountSettings.tsx", 91]],
|
||||
"translation": "Sie sind dabei, Ihr Passwort zu ändern."
|
||||
},
|
||||
"3WXdoZ": {
|
||||
"translation": "Sie können diese später jederzeit in den Einstellungen ändern.",
|
||||
"message": "You can always change these later in settings.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 182]]
|
||||
},
|
||||
"aelko+": {
|
||||
"message": "You can get a custom workspace URL, like <0>kan.bn/kan</0>, by going into your <1>workspace settings</1> and purchasing a pro workspace subscription. All subscriptions help fund the development of the project!",
|
||||
"placeholders": {},
|
||||
@@ -6467,8 +6808,8 @@
|
||||
["src/views/board/components/List.tsx", 117],
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 58],
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 487],
|
||||
["src/views/board/index.tsx", 545],
|
||||
["src/views/board/index.tsx", 603],
|
||||
["src/views/board/index.tsx", 661],
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
@@ -6533,6 +6874,13 @@
|
||||
],
|
||||
"translation": "Ihr Konto wurde gelöscht."
|
||||
},
|
||||
"c4nMcR": {
|
||||
"translation": "Ihr Avatar",
|
||||
"message": "Your avatar",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 229]]
|
||||
},
|
||||
"evg7+A": {
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
@@ -6619,6 +6967,20 @@
|
||||
"origin": [["src/pages/unsubscribe/index.tsx", 33]],
|
||||
"translation": "Ihrem Abmelde-Link fehlt ein Token. Bitte öffnen Sie die neueste E-Mail und versuchen Sie es erneut."
|
||||
},
|
||||
"GRAGsB": {
|
||||
"translation": "Ihr Workspace",
|
||||
"message": "Your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 322]]
|
||||
},
|
||||
"j0o6ml": {
|
||||
"translation": "Ihre Workspace-Beschreibung",
|
||||
"message": "Your workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 325]]
|
||||
},
|
||||
"GnSSGm": {
|
||||
"message": "Your workspace description has been updated.",
|
||||
"placeholders": {},
|
||||
@@ -6655,6 +7017,16 @@
|
||||
],
|
||||
"translation": "Ihr Workspace-Slug wurde aktualisiert."
|
||||
},
|
||||
"OTxjpR": {
|
||||
"translation": "ihr-workspace",
|
||||
"message": "your-workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 197],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 198]
|
||||
]
|
||||
},
|
||||
"4DOCMI": {
|
||||
"message": "YouTube URL",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -71,7 +71,7 @@
|
||||
"0": ["isTemplate ? \"Template\" : \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 440]],
|
||||
"origin": [["src/views/board/index.tsx", 556]],
|
||||
"translation": "{0} no encontrado"
|
||||
},
|
||||
"0xWkkH": {
|
||||
@@ -238,6 +238,13 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 110]],
|
||||
"translation": "Registros de actividad"
|
||||
},
|
||||
"UGCIzB": {
|
||||
"message": "Add / edit label",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 50]],
|
||||
"translation": "Añadir / editar etiqueta"
|
||||
},
|
||||
"B3xxao": {
|
||||
"message": "Add a card",
|
||||
"placeholders": {},
|
||||
@@ -288,8 +295,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/LabelSelector.tsx", 113],
|
||||
["src/views/card/components/LabelSelector.tsx", 118]
|
||||
["src/views/card/components/LabelSelector.tsx", 114],
|
||||
["src/views/card/components/LabelSelector.tsx", 119]
|
||||
],
|
||||
"translation": "Añadir etiqueta"
|
||||
},
|
||||
@@ -298,7 +305,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 134],
|
||||
["src/views/card/components/MemberSelector.tsx", 135],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 257]
|
||||
],
|
||||
"translation": "Añadir miembro"
|
||||
@@ -549,6 +556,13 @@
|
||||
],
|
||||
"translation": "Se produjo un error inesperado. Por favor, inténtalo de nuevo más tarde."
|
||||
},
|
||||
"YkfDoz": {
|
||||
"translation": "Anual",
|
||||
"message": "Annual",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 63]]
|
||||
},
|
||||
"3bqt9U": {
|
||||
"message": "Anyone with this link can join your workspace",
|
||||
"placeholders": {},
|
||||
@@ -749,6 +763,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 59]],
|
||||
"translation": "Esperando al cliente"
|
||||
},
|
||||
"iH8pgl": {
|
||||
"translation": "Atrás",
|
||||
"message": "Back",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 275]]
|
||||
},
|
||||
"KNKCTb": {
|
||||
"message": "Backlog",
|
||||
"placeholders": {},
|
||||
@@ -791,6 +812,13 @@
|
||||
"origin": [["src/views/pricing/components/PricingTiers.tsx", 53]],
|
||||
"translation": "Ideal para equipos pequeños y en crecimiento que necesitan colaboración"
|
||||
},
|
||||
"zt/6cS": {
|
||||
"translation": "Ideal para equipos pequeños que desean colaborar y avanzar más rápido juntos.",
|
||||
"message": "Best for small teams who want to collaborate and move faster together.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 86]]
|
||||
},
|
||||
"qaS+1/": {
|
||||
"message": "Best for teams that want to scale without limits",
|
||||
"placeholders": {},
|
||||
@@ -842,7 +870,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/card/index.tsx", 317],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
@@ -1235,12 +1263,14 @@
|
||||
"origin": [
|
||||
["src/components/DeleteLabelConfirmation.tsx", 49],
|
||||
["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 176],
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 267],
|
||||
["src/views/board/components/DeleteBoardConfirmation.tsx", 44],
|
||||
["src/views/card/components/Comment.tsx", 195],
|
||||
["src/views/card/components/DeleteCardConfirmation.tsx", 86],
|
||||
["src/views/card/components/DeleteChecklistConfirmation.tsx", 64],
|
||||
["src/views/card/components/DeleteCommentConfirmation.tsx", 77],
|
||||
["src/views/members/components/DeleteMemberConfirmation.tsx", 55],
|
||||
["src/views/onboarding/select-plan/index.tsx", 209],
|
||||
["src/views/settings/components/Avatar.tsx", 287],
|
||||
["src/views/settings/components/ChangePasswordConfirmation.tsx", 168],
|
||||
[
|
||||
@@ -1261,6 +1291,15 @@
|
||||
"origin": [["src/views/card/index.tsx", 317]],
|
||||
"translation": "Tarjeta"
|
||||
},
|
||||
"sU2uWc": {
|
||||
"message": "Card duplicated",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 67]
|
||||
],
|
||||
"translation": "Tarjeta duplicada"
|
||||
},
|
||||
"fEY2vP": {
|
||||
"message": "Card not found",
|
||||
"placeholders": {},
|
||||
@@ -1283,6 +1322,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 307],
|
||||
["src/views/card/components/Dropdown.tsx", 44],
|
||||
["src/views/public/board/CardModal.tsx", 38]
|
||||
],
|
||||
@@ -1360,6 +1400,13 @@
|
||||
],
|
||||
"translation": "Listas de verificación"
|
||||
},
|
||||
"zMquA7": {
|
||||
"translation": "Elige un plan",
|
||||
"message": "Choose a plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 122]]
|
||||
},
|
||||
"VHS0aJ": {
|
||||
"message": "Clear all custom permissions?",
|
||||
"placeholders": {},
|
||||
@@ -1617,6 +1664,16 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 40]],
|
||||
"translation": "Creación de contenido"
|
||||
},
|
||||
"xGVfLh": {
|
||||
"translation": "Continuar",
|
||||
"message": "Continue",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 212],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 291]
|
||||
]
|
||||
},
|
||||
"J2Wbjt": {
|
||||
"message": "Continue with ",
|
||||
"placeholders": {},
|
||||
@@ -1661,6 +1718,40 @@
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 58]],
|
||||
"translation": "Copiar enlace de la tarjeta"
|
||||
},
|
||||
"0utuU6": {
|
||||
"message": "Copy checklists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 257]
|
||||
],
|
||||
"translation": "Copiar listas de verificación"
|
||||
},
|
||||
"fDQ7hA": {
|
||||
"message": "Copy labels",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 221]
|
||||
],
|
||||
"translation": "Copiar etiquetas"
|
||||
},
|
||||
"1bJKhj": {
|
||||
"message": "Copy link to card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 62]],
|
||||
"translation": "Copiar enlace a la tarjeta"
|
||||
},
|
||||
"uvH2xS": {
|
||||
"message": "Copy members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 239]
|
||||
],
|
||||
"translation": "Copiar miembros"
|
||||
},
|
||||
"9PaIxv": {
|
||||
"message": "Core features",
|
||||
"placeholders": {},
|
||||
@@ -1757,7 +1848,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewCardForm.tsx", 417],
|
||||
["src/views/card/components/LabelSelector.tsx", 100]
|
||||
["src/views/card/components/LabelSelector.tsx", 101]
|
||||
],
|
||||
"translation": "Crear nueva etiqueta"
|
||||
},
|
||||
@@ -1766,8 +1857,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 76],
|
||||
["src/views/board/index.tsx", 554]
|
||||
["src/views/board/index.tsx", 91],
|
||||
["src/views/board/index.tsx", 670]
|
||||
],
|
||||
"translation": "Crear nueva lista"
|
||||
},
|
||||
@@ -1791,7 +1882,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 388],
|
||||
["src/components/WorkspaceMenu.tsx", 153]
|
||||
["src/components/WorkspaceMenu.tsx", 160]
|
||||
],
|
||||
"translation": "Crear espacio de trabajo"
|
||||
},
|
||||
@@ -1891,6 +1982,13 @@
|
||||
],
|
||||
"translation": "Nombre de usuario personalizado"
|
||||
},
|
||||
"ZDPJBc": {
|
||||
"translation": "Los nombres de usuario personalizados requieren actualizar a un plan Pro",
|
||||
"message": "Custom usernames require upgrading to a Pro plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 220]]
|
||||
},
|
||||
"j9IZZ0": {
|
||||
"message": "Custom workspace URL",
|
||||
"placeholders": {},
|
||||
@@ -1985,7 +2083,10 @@
|
||||
"message": "Delete card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 76]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMenu.tsx", 74],
|
||||
["src/views/card/components/Dropdown.tsx", 76]
|
||||
],
|
||||
"translation": "Eliminar tarjeta"
|
||||
},
|
||||
"njJFtc": {
|
||||
@@ -2171,6 +2272,9 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 36],
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 48],
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 68],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 17],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 23],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 29],
|
||||
@@ -2226,6 +2330,34 @@
|
||||
"origin": [["src/views/board/components/Filters.tsx", 122]],
|
||||
"translation": "Vence mañana"
|
||||
},
|
||||
"euc6Ns": {
|
||||
"message": "Duplicate",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplicar"
|
||||
},
|
||||
"BTDPLo": {
|
||||
"message": "Duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 111],
|
||||
["src/views/board/components/CardContextMenu.tsx", 68]
|
||||
],
|
||||
"translation": "Duplicar tarjeta"
|
||||
},
|
||||
"06EQqT": {
|
||||
"message": "Duplicating…",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplicando…"
|
||||
},
|
||||
"ePK91l": {
|
||||
"message": "Edit",
|
||||
"placeholders": {},
|
||||
@@ -2338,6 +2470,22 @@
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 100]],
|
||||
"translation": "Visibilidad del email"
|
||||
},
|
||||
"bFREhu": {
|
||||
"message": "End of list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 200]
|
||||
],
|
||||
"translation": "Fin de la lista"
|
||||
},
|
||||
"SUXBxp": {
|
||||
"translation": "Ingeniería",
|
||||
"message": "Engineering",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"0+ewPp": {
|
||||
"message": "Enhancement",
|
||||
"placeholders": {},
|
||||
@@ -2794,6 +2942,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 77],
|
||||
["src/views/onboarding/select-plan/index.tsx", 78],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 331],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
@@ -2894,7 +3044,7 @@
|
||||
"message": "Get started by creating a new list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 539]],
|
||||
"origin": [["src/views/board/index.tsx", 655]],
|
||||
"translation": "Comienza creando una nueva lista"
|
||||
},
|
||||
"oW13KZ": {
|
||||
@@ -3004,6 +3154,13 @@
|
||||
"origin": [["src/components/SideNavigation.tsx", 119]],
|
||||
"translation": "Ir a plantillas"
|
||||
},
|
||||
"SUvm1Y": {
|
||||
"translation": "Ideal para personas que comienzan y solo necesitan lo esencial.",
|
||||
"message": "Good for individuals starting out who just need the essentials.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 79]]
|
||||
},
|
||||
"cdyS7J": {
|
||||
"message": "Google SSO",
|
||||
"placeholders": {},
|
||||
@@ -3314,7 +3471,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 114],
|
||||
["src/views/card/components/MemberSelector.tsx", 115],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 367]
|
||||
],
|
||||
"translation": "Invitar miembro"
|
||||
@@ -3386,6 +3543,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 31],
|
||||
["src/views/board/components/Filters.tsx", 155],
|
||||
["src/views/board/components/NewCardForm.tsx", 421],
|
||||
["src/views/card/index.tsx", 133]
|
||||
@@ -3497,6 +3655,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 80],
|
||||
["src/views/board/index.tsx", 305],
|
||||
["src/views/card/components/Dropdown.tsx", 42],
|
||||
["src/views/public/board/CardModal.tsx", 36],
|
||||
["src/views/public/board/index.tsx", 77]
|
||||
@@ -3507,7 +3666,10 @@
|
||||
"message": "List",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 124]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 117],
|
||||
["src/views/card/index.tsx", 124]
|
||||
],
|
||||
"translation": "Lista"
|
||||
},
|
||||
"zQX5Dj": {
|
||||
@@ -3596,6 +3758,16 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Crear plantilla"
|
||||
},
|
||||
"hB02vO": {
|
||||
"message": "Manage members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 51],
|
||||
["src/views/board/components/CardContextMenu.tsx", 38]
|
||||
],
|
||||
"translation": "Gestionar miembros"
|
||||
},
|
||||
"IDvohQ": {
|
||||
"message": "marked a checklist item as incomplete",
|
||||
"placeholders": {},
|
||||
@@ -3612,6 +3784,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 258]],
|
||||
"translation": "marcó el elemento de la lista de verificación <0>{0}</0> como incompleto"
|
||||
},
|
||||
"vo2a+a": {
|
||||
"translation": "Marketing",
|
||||
"message": "Marketing",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"agPptk": {
|
||||
"message": "Medium",
|
||||
"placeholders": {},
|
||||
@@ -3683,6 +3862,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 62],
|
||||
["src/views/pricing/components/Pricing.tsx", 14],
|
||||
["src/views/pricing/index.tsx", 20]
|
||||
],
|
||||
@@ -3695,6 +3875,20 @@
|
||||
"origin": [["src/views/members/components/InviteMemberForm.tsx", 159]],
|
||||
"translation": "facturación mensual"
|
||||
},
|
||||
"51UCsN": {
|
||||
"message": "Move to another list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 44]],
|
||||
"translation": "Mover a otra lista"
|
||||
},
|
||||
"J4+OTA": {
|
||||
"message": "Move to list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 70]],
|
||||
"translation": "Mover a lista"
|
||||
},
|
||||
"BOqTi5": {
|
||||
"message": "moved the card from <0>{0}</0> to<1>{1}</1>",
|
||||
"placeholders": {
|
||||
@@ -3806,7 +4000,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewListForm.tsx", 113],
|
||||
["src/views/board/index.tsx", 503]
|
||||
["src/views/board/index.tsx", 619]
|
||||
],
|
||||
"translation": "Nueva lista"
|
||||
},
|
||||
@@ -3932,14 +4126,14 @@
|
||||
"message": "No lists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 535]],
|
||||
"origin": [["src/views/board/index.tsx", 651]],
|
||||
"translation": "Sin listas"
|
||||
},
|
||||
"fvLNDy": {
|
||||
"message": "No lists have been created yet",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 540]],
|
||||
"origin": [["src/views/board/index.tsx", 656]],
|
||||
"translation": "Aún no se han creado listas"
|
||||
},
|
||||
"i30J2U": {
|
||||
@@ -4020,7 +4214,7 @@
|
||||
"message": "Open command menu",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 31]],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 34]],
|
||||
"translation": "Abrir menú de comandos"
|
||||
},
|
||||
"cFQEU/": {
|
||||
@@ -4236,6 +4430,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 86]],
|
||||
"translation": "Proyecto personal"
|
||||
},
|
||||
"Oi+J+N": {
|
||||
"translation": "Elige un plan para comenzar. Todos los planes de pago incluyen una prueba gratuita de 14 días.",
|
||||
"message": "Pick a plan to get started. All paid plans include a 14-day free trial.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 125]]
|
||||
},
|
||||
"Iqh0Uv": {
|
||||
"message": "Planned",
|
||||
"placeholders": {},
|
||||
@@ -4331,8 +4532,8 @@
|
||||
["src/views/board/components/NewTemplateForm.tsx", 77],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 73],
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 194],
|
||||
["src/views/board/index.tsx", 250],
|
||||
["src/views/board/index.tsx", 217],
|
||||
["src/views/board/index.tsx", 273],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
@@ -4360,6 +4561,8 @@
|
||||
["src/views/members/components/InviteMemberForm.tsx", 104],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 241],
|
||||
["src/views/members/index.tsx", 66],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 101],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 150],
|
||||
["src/views/settings/components/Avatar.tsx", 200],
|
||||
["src/views/settings/components/DeleteAccountConfirmation.tsx", 40],
|
||||
["src/views/settings/components/DeleteWorkspaceConfirmation.tsx", 46],
|
||||
@@ -4387,12 +4590,24 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 76],
|
||||
["src/views/board/components/CardContextMoveListModal.tsx", 42],
|
||||
["src/views/board/index.tsx", 314],
|
||||
["src/views/card/components/Dropdown.tsx", 51],
|
||||
["src/views/public/board/CardModal.tsx", 45],
|
||||
["src/views/public/board/index.tsx", 86]
|
||||
],
|
||||
"translation": "Por favor, inténtalo de nuevo."
|
||||
},
|
||||
"nYNMZZ": {
|
||||
"message": "Position in list (0 = first, leave empty for end)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 193]
|
||||
],
|
||||
"translation": "Posición en la lista (0 = primero, dejar vacío para el final)"
|
||||
},
|
||||
"aHCEmh": {
|
||||
"message": "Pricing",
|
||||
"placeholders": {},
|
||||
@@ -4438,6 +4653,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 91],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 333],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 70]
|
||||
],
|
||||
@@ -4695,7 +4911,8 @@
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 36],
|
||||
["src/views/home/components/Header.tsx", 13],
|
||||
["src/views/home/components/Header.tsx", 28]
|
||||
["src/views/home/components/Header.tsx", 28],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 161]
|
||||
],
|
||||
"translation": "Hoja de ruta"
|
||||
},
|
||||
@@ -4814,6 +5031,15 @@
|
||||
"origin": [["src/views/home/components/Testimonials.tsx", 239]],
|
||||
"translation": "Mira lo que nuestros usuarios dicen sobre Kan"
|
||||
},
|
||||
"zYRVNp": {
|
||||
"message": "Select a list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 131]
|
||||
],
|
||||
"translation": "Seleccionar una lista"
|
||||
},
|
||||
"wgNoIs": {
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
@@ -4884,7 +5110,11 @@
|
||||
"message": "Set due date",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/DueDateSelector.tsx", 121]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 20],
|
||||
["src/views/board/components/CardContextMenu.tsx", 56],
|
||||
["src/views/card/components/DueDateSelector.tsx", 121]
|
||||
],
|
||||
"translation": "Establecer fecha de vencimiento"
|
||||
},
|
||||
"Eit43O": {
|
||||
@@ -4894,6 +5124,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 142]],
|
||||
"translation": "estableció la fecha de vencimiento"
|
||||
},
|
||||
"JjEJSy": {
|
||||
"translation": "Configura tu espacio de trabajo",
|
||||
"message": "Set up your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 179]]
|
||||
},
|
||||
"Tz0i8g": {
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
@@ -4974,6 +5211,16 @@
|
||||
"origin": [["src/views/invite/index.tsx", 154]],
|
||||
"translation": "Iniciar sesión"
|
||||
},
|
||||
"fcWrnU": {
|
||||
"translation": "Cerrar sesión",
|
||||
"message": "Sign out",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 284],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 362]
|
||||
]
|
||||
},
|
||||
"mErq7F": {
|
||||
"message": "Sign Up",
|
||||
"placeholders": {},
|
||||
@@ -5059,6 +5306,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 22]],
|
||||
"translation": "Desarrollo de software"
|
||||
},
|
||||
"6sKjjx": {
|
||||
"translation": "Individual",
|
||||
"message": "Solo",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 76]]
|
||||
},
|
||||
"vnS6Rf": {
|
||||
"message": "SSO",
|
||||
"placeholders": {},
|
||||
@@ -5158,6 +5412,13 @@
|
||||
"origin": [["src/components/UserMenu.tsx", 144]],
|
||||
"translation": "Sistema"
|
||||
},
|
||||
"KM6m8p": {
|
||||
"translation": "Equipo",
|
||||
"message": "Team",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 83]]
|
||||
},
|
||||
"bff61F": {
|
||||
"message": "Team Plan",
|
||||
"placeholders": {},
|
||||
@@ -5184,8 +5445,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 449]
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/board/index.tsx", 565]
|
||||
],
|
||||
"translation": "Plantilla"
|
||||
},
|
||||
@@ -5279,6 +5540,15 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "El tablero ha sido desarchivado."
|
||||
},
|
||||
"nKBUeF": {
|
||||
"message": "The card has been duplicated.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 69]
|
||||
],
|
||||
"translation": "La tarjeta ha sido duplicada."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5401,6 +5671,20 @@
|
||||
],
|
||||
"translation": "Los permisos de este miembro se han restablecido a los valores predeterminados de su rol."
|
||||
},
|
||||
"HQVm6e": {
|
||||
"translation": "Esta URL ya está en uso",
|
||||
"message": "This URL has already been taken",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 73]]
|
||||
},
|
||||
"gKmoow": {
|
||||
"translation": "Esta URL está reservada",
|
||||
"message": "This URL is reserved",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 75]]
|
||||
},
|
||||
"OAYToL": {
|
||||
"message": "This will remove all custom member permissions in this workspace. Members will inherit permissions only from their roles.",
|
||||
"placeholders": {},
|
||||
@@ -5461,6 +5745,15 @@
|
||||
"origin": [["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 127]],
|
||||
"translation": "Título"
|
||||
},
|
||||
"wK4OTM": {
|
||||
"message": "Title (optional)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 180]
|
||||
],
|
||||
"translation": "Título (opcional)"
|
||||
},
|
||||
"Se/UIp": {
|
||||
"message": "To Do",
|
||||
"placeholders": {},
|
||||
@@ -5563,6 +5856,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 312],
|
||||
["src/views/card/components/Dropdown.tsx", 49],
|
||||
["src/views/public/board/CardModal.tsx", 43],
|
||||
["src/views/public/board/index.tsx", 84]
|
||||
@@ -5604,7 +5898,10 @@
|
||||
"message": "Unable to create workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 158]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 100]
|
||||
],
|
||||
"translation": "No se pudo crear el espacio de trabajo"
|
||||
},
|
||||
"WHHLh9": {
|
||||
@@ -5644,6 +5941,22 @@
|
||||
"origin": [["src/views/card/components/DeleteCommentConfirmation.tsx", 45]],
|
||||
"translation": "No se pudo eliminar el comentario"
|
||||
},
|
||||
"Oo4E6p": {
|
||||
"message": "Unable to duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 75]
|
||||
],
|
||||
"translation": "No se puede duplicar la tarjeta"
|
||||
},
|
||||
"K7k9u3": {
|
||||
"message": "Unable to move card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 41]],
|
||||
"translation": "No se puede mover la tarjeta"
|
||||
},
|
||||
"8yFGGF": {
|
||||
"message": "Unable to remove member",
|
||||
"placeholders": {},
|
||||
@@ -5676,6 +5989,13 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 40]],
|
||||
"translation": "No se pudo enviar el comentario"
|
||||
},
|
||||
"Q60WUZ": {
|
||||
"translation": "No se pudo iniciar el proceso de pago",
|
||||
"message": "Unable to start checkout",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 149]]
|
||||
},
|
||||
"T7Mywq": {
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
@@ -5702,7 +6022,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 249],
|
||||
["src/views/board/index.tsx", 272],
|
||||
["src/views/card/index.tsx", 231]
|
||||
],
|
||||
"translation": "No se pudo actualizar la tarjeta"
|
||||
@@ -5747,7 +6067,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 193],
|
||||
["src/views/board/index.tsx", 216],
|
||||
["src/views/card/components/ListSelector.tsx", 54]
|
||||
],
|
||||
"translation": "No se pudo actualizar la lista"
|
||||
@@ -5883,6 +6203,13 @@
|
||||
],
|
||||
"translation": "Miembros ilimitados"
|
||||
},
|
||||
"8AwlaR": {
|
||||
"translation": "Miembros ilimitados y un nombre de usuario personalizado para el espacio de trabajo para equipos listos para escalar.",
|
||||
"message": "Unlimited members and a custom workspace username for teams ready to scale.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 94]]
|
||||
},
|
||||
"Ws+3X+": {
|
||||
"message": "Unlimited seats and advanced features for growing teams.",
|
||||
"placeholders": {},
|
||||
@@ -5972,7 +6299,10 @@
|
||||
"message": "Upgrade to Pro ($29/month)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 373]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 373],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 243]
|
||||
],
|
||||
"translation": "Actualizar a Pro ($29/mes)"
|
||||
},
|
||||
"b3Thhd": {
|
||||
@@ -6256,7 +6586,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 47],
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
@@ -6284,7 +6614,10 @@
|
||||
"message": "Workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 82]],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 253],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 82]
|
||||
],
|
||||
"translation": "Descripción del espacio de trabajo"
|
||||
},
|
||||
"Ax/hYa": {
|
||||
@@ -6331,6 +6664,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 263],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 188],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 63]
|
||||
],
|
||||
"translation": "Nombre del espacio de trabajo"
|
||||
@@ -6438,6 +6772,13 @@
|
||||
"origin": [["src/views/settings/AccountSettings.tsx", 91]],
|
||||
"translation": "Estás a punto de cambiar tu contraseña."
|
||||
},
|
||||
"3WXdoZ": {
|
||||
"translation": "Siempre puedes cambiar esto más tarde en la configuración.",
|
||||
"message": "You can always change these later in settings.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 182]]
|
||||
},
|
||||
"aelko+": {
|
||||
"message": "You can get a custom workspace URL, like <0>kan.bn/kan</0>, by going into your <1>workspace settings</1> and purchasing a pro workspace subscription. All subscriptions help fund the development of the project!",
|
||||
"placeholders": {},
|
||||
@@ -6467,8 +6808,8 @@
|
||||
["src/views/board/components/List.tsx", 117],
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 58],
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 487],
|
||||
["src/views/board/index.tsx", 545],
|
||||
["src/views/board/index.tsx", 603],
|
||||
["src/views/board/index.tsx", 661],
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
@@ -6533,6 +6874,13 @@
|
||||
],
|
||||
"translation": "Tu cuenta ha sido eliminada."
|
||||
},
|
||||
"c4nMcR": {
|
||||
"translation": "Tu avatar",
|
||||
"message": "Your avatar",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 229]]
|
||||
},
|
||||
"evg7+A": {
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
@@ -6619,6 +6967,20 @@
|
||||
"origin": [["src/pages/unsubscribe/index.tsx", 33]],
|
||||
"translation": "Tu enlace de cancelación de suscripción no tiene un token. Por favor, abre el último correo electrónico e inténtalo de nuevo."
|
||||
},
|
||||
"GRAGsB": {
|
||||
"translation": "Tu espacio de trabajo",
|
||||
"message": "Your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 322]]
|
||||
},
|
||||
"j0o6ml": {
|
||||
"translation": "Descripción de tu espacio de trabajo",
|
||||
"message": "Your workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 325]]
|
||||
},
|
||||
"GnSSGm": {
|
||||
"message": "Your workspace description has been updated.",
|
||||
"placeholders": {},
|
||||
@@ -6655,6 +7017,16 @@
|
||||
],
|
||||
"translation": "El slug de tu espacio de trabajo ha sido actualizado."
|
||||
},
|
||||
"OTxjpR": {
|
||||
"translation": "tu-espacio-de-trabajo",
|
||||
"message": "your-workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 197],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 198]
|
||||
]
|
||||
},
|
||||
"4DOCMI": {
|
||||
"message": "YouTube URL",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -71,7 +71,7 @@
|
||||
"0": ["isTemplate ? \"Template\" : \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 440]],
|
||||
"origin": [["src/views/board/index.tsx", 556]],
|
||||
"translation": "{0} introuvable"
|
||||
},
|
||||
"0xWkkH": {
|
||||
@@ -238,6 +238,13 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 110]],
|
||||
"translation": "Journaux d'activité"
|
||||
},
|
||||
"UGCIzB": {
|
||||
"message": "Add / edit label",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 50]],
|
||||
"translation": "Ajouter / modifier l'étiquette"
|
||||
},
|
||||
"B3xxao": {
|
||||
"message": "Add a card",
|
||||
"placeholders": {},
|
||||
@@ -288,8 +295,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/LabelSelector.tsx", 113],
|
||||
["src/views/card/components/LabelSelector.tsx", 118]
|
||||
["src/views/card/components/LabelSelector.tsx", 114],
|
||||
["src/views/card/components/LabelSelector.tsx", 119]
|
||||
],
|
||||
"translation": "Ajouter une étiquette"
|
||||
},
|
||||
@@ -298,7 +305,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 134],
|
||||
["src/views/card/components/MemberSelector.tsx", 135],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 257]
|
||||
],
|
||||
"translation": "Ajouter un membre"
|
||||
@@ -549,6 +556,13 @@
|
||||
],
|
||||
"translation": "Une erreur inattendue s'est produite. Veuillez réessayer ultérieurement."
|
||||
},
|
||||
"YkfDoz": {
|
||||
"translation": "Annuel",
|
||||
"message": "Annual",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 63]]
|
||||
},
|
||||
"3bqt9U": {
|
||||
"message": "Anyone with this link can join your workspace",
|
||||
"placeholders": {},
|
||||
@@ -749,6 +763,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 59]],
|
||||
"translation": "En attente du client"
|
||||
},
|
||||
"iH8pgl": {
|
||||
"translation": "Retour",
|
||||
"message": "Back",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 275]]
|
||||
},
|
||||
"KNKCTb": {
|
||||
"message": "Backlog",
|
||||
"placeholders": {},
|
||||
@@ -791,6 +812,13 @@
|
||||
"origin": [["src/views/pricing/components/PricingTiers.tsx", 53]],
|
||||
"translation": "Idéal pour les petites équipes en croissance qui ont besoin de collaboration"
|
||||
},
|
||||
"zt/6cS": {
|
||||
"translation": "Idéal pour les petites équipes qui souhaitent collaborer et avancer plus rapidement ensemble.",
|
||||
"message": "Best for small teams who want to collaborate and move faster together.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 86]]
|
||||
},
|
||||
"qaS+1/": {
|
||||
"message": "Best for teams that want to scale without limits",
|
||||
"placeholders": {},
|
||||
@@ -842,7 +870,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/card/index.tsx", 317],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
@@ -1235,12 +1263,14 @@
|
||||
"origin": [
|
||||
["src/components/DeleteLabelConfirmation.tsx", 49],
|
||||
["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 176],
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 267],
|
||||
["src/views/board/components/DeleteBoardConfirmation.tsx", 44],
|
||||
["src/views/card/components/Comment.tsx", 195],
|
||||
["src/views/card/components/DeleteCardConfirmation.tsx", 86],
|
||||
["src/views/card/components/DeleteChecklistConfirmation.tsx", 64],
|
||||
["src/views/card/components/DeleteCommentConfirmation.tsx", 77],
|
||||
["src/views/members/components/DeleteMemberConfirmation.tsx", 55],
|
||||
["src/views/onboarding/select-plan/index.tsx", 209],
|
||||
["src/views/settings/components/Avatar.tsx", 287],
|
||||
["src/views/settings/components/ChangePasswordConfirmation.tsx", 168],
|
||||
[
|
||||
@@ -1261,6 +1291,15 @@
|
||||
"origin": [["src/views/card/index.tsx", 317]],
|
||||
"translation": "Carte"
|
||||
},
|
||||
"sU2uWc": {
|
||||
"message": "Card duplicated",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 67]
|
||||
],
|
||||
"translation": "Carte dupliquée"
|
||||
},
|
||||
"fEY2vP": {
|
||||
"message": "Card not found",
|
||||
"placeholders": {},
|
||||
@@ -1283,6 +1322,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 307],
|
||||
["src/views/card/components/Dropdown.tsx", 44],
|
||||
["src/views/public/board/CardModal.tsx", 38]
|
||||
],
|
||||
@@ -1360,6 +1400,13 @@
|
||||
],
|
||||
"translation": "Checklists"
|
||||
},
|
||||
"zMquA7": {
|
||||
"translation": "Choisir un forfait",
|
||||
"message": "Choose a plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 122]]
|
||||
},
|
||||
"VHS0aJ": {
|
||||
"message": "Clear all custom permissions?",
|
||||
"placeholders": {},
|
||||
@@ -1617,6 +1664,16 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 40]],
|
||||
"translation": "Création de contenu"
|
||||
},
|
||||
"xGVfLh": {
|
||||
"translation": "Continuer",
|
||||
"message": "Continue",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 212],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 291]
|
||||
]
|
||||
},
|
||||
"J2Wbjt": {
|
||||
"message": "Continue with ",
|
||||
"placeholders": {},
|
||||
@@ -1661,6 +1718,40 @@
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 58]],
|
||||
"translation": "Copier le lien de la carte"
|
||||
},
|
||||
"0utuU6": {
|
||||
"message": "Copy checklists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 257]
|
||||
],
|
||||
"translation": "Copier les listes de contrôle"
|
||||
},
|
||||
"fDQ7hA": {
|
||||
"message": "Copy labels",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 221]
|
||||
],
|
||||
"translation": "Copier les étiquettes"
|
||||
},
|
||||
"1bJKhj": {
|
||||
"message": "Copy link to card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 62]],
|
||||
"translation": "Copier le lien vers la carte"
|
||||
},
|
||||
"uvH2xS": {
|
||||
"message": "Copy members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 239]
|
||||
],
|
||||
"translation": "Copier les membres"
|
||||
},
|
||||
"9PaIxv": {
|
||||
"message": "Core features",
|
||||
"placeholders": {},
|
||||
@@ -1757,7 +1848,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewCardForm.tsx", 417],
|
||||
["src/views/card/components/LabelSelector.tsx", 100]
|
||||
["src/views/card/components/LabelSelector.tsx", 101]
|
||||
],
|
||||
"translation": "Créer une nouvelle étiquette"
|
||||
},
|
||||
@@ -1766,8 +1857,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 76],
|
||||
["src/views/board/index.tsx", 554]
|
||||
["src/views/board/index.tsx", 91],
|
||||
["src/views/board/index.tsx", 670]
|
||||
],
|
||||
"translation": "Créer une nouvelle liste"
|
||||
},
|
||||
@@ -1791,7 +1882,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 388],
|
||||
["src/components/WorkspaceMenu.tsx", 153]
|
||||
["src/components/WorkspaceMenu.tsx", 160]
|
||||
],
|
||||
"translation": "Créer un espace de travail"
|
||||
},
|
||||
@@ -1891,6 +1982,13 @@
|
||||
],
|
||||
"translation": "Nom d'utilisateur personnalisé"
|
||||
},
|
||||
"ZDPJBc": {
|
||||
"translation": "Les noms d'utilisateur personnalisés nécessitent une mise à niveau vers un forfait Pro",
|
||||
"message": "Custom usernames require upgrading to a Pro plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 220]]
|
||||
},
|
||||
"j9IZZ0": {
|
||||
"message": "Custom workspace URL",
|
||||
"placeholders": {},
|
||||
@@ -1985,7 +2083,10 @@
|
||||
"message": "Delete card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 76]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMenu.tsx", 74],
|
||||
["src/views/card/components/Dropdown.tsx", 76]
|
||||
],
|
||||
"translation": "Supprimer la carte"
|
||||
},
|
||||
"njJFtc": {
|
||||
@@ -2171,6 +2272,9 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 36],
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 48],
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 68],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 17],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 23],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 29],
|
||||
@@ -2226,6 +2330,34 @@
|
||||
"origin": [["src/views/board/components/Filters.tsx", 122]],
|
||||
"translation": "Échéance demain"
|
||||
},
|
||||
"euc6Ns": {
|
||||
"message": "Duplicate",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Dupliquer"
|
||||
},
|
||||
"BTDPLo": {
|
||||
"message": "Duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 111],
|
||||
["src/views/board/components/CardContextMenu.tsx", 68]
|
||||
],
|
||||
"translation": "Dupliquer la carte"
|
||||
},
|
||||
"06EQqT": {
|
||||
"message": "Duplicating…",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplication en cours…"
|
||||
},
|
||||
"ePK91l": {
|
||||
"message": "Edit",
|
||||
"placeholders": {},
|
||||
@@ -2338,6 +2470,22 @@
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 100]],
|
||||
"translation": "Visibilité de l'e-mail"
|
||||
},
|
||||
"bFREhu": {
|
||||
"message": "End of list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 200]
|
||||
],
|
||||
"translation": "Fin de la liste"
|
||||
},
|
||||
"SUXBxp": {
|
||||
"translation": "Ingénierie",
|
||||
"message": "Engineering",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"0+ewPp": {
|
||||
"message": "Enhancement",
|
||||
"placeholders": {},
|
||||
@@ -2794,6 +2942,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 77],
|
||||
["src/views/onboarding/select-plan/index.tsx", 78],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 331],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
@@ -2894,7 +3044,7 @@
|
||||
"message": "Get started by creating a new list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 539]],
|
||||
"origin": [["src/views/board/index.tsx", 655]],
|
||||
"translation": "Commencez en créant une nouvelle liste"
|
||||
},
|
||||
"oW13KZ": {
|
||||
@@ -3004,6 +3154,13 @@
|
||||
"origin": [["src/components/SideNavigation.tsx", 119]],
|
||||
"translation": "Aller aux modèles"
|
||||
},
|
||||
"SUvm1Y": {
|
||||
"translation": "Idéal pour les particuliers qui débutent et qui ont simplement besoin de l'essentiel.",
|
||||
"message": "Good for individuals starting out who just need the essentials.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 79]]
|
||||
},
|
||||
"cdyS7J": {
|
||||
"message": "Google SSO",
|
||||
"placeholders": {},
|
||||
@@ -3314,7 +3471,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 114],
|
||||
["src/views/card/components/MemberSelector.tsx", 115],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 367]
|
||||
],
|
||||
"translation": "Inviter un membre"
|
||||
@@ -3386,6 +3543,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 31],
|
||||
["src/views/board/components/Filters.tsx", 155],
|
||||
["src/views/board/components/NewCardForm.tsx", 421],
|
||||
["src/views/card/index.tsx", 133]
|
||||
@@ -3497,6 +3655,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 80],
|
||||
["src/views/board/index.tsx", 305],
|
||||
["src/views/card/components/Dropdown.tsx", 42],
|
||||
["src/views/public/board/CardModal.tsx", 36],
|
||||
["src/views/public/board/index.tsx", 77]
|
||||
@@ -3507,7 +3666,10 @@
|
||||
"message": "List",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 124]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 117],
|
||||
["src/views/card/index.tsx", 124]
|
||||
],
|
||||
"translation": "Liste"
|
||||
},
|
||||
"zQX5Dj": {
|
||||
@@ -3596,6 +3758,16 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Créer un modèle"
|
||||
},
|
||||
"hB02vO": {
|
||||
"message": "Manage members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 51],
|
||||
["src/views/board/components/CardContextMenu.tsx", 38]
|
||||
],
|
||||
"translation": "Gérer les membres"
|
||||
},
|
||||
"IDvohQ": {
|
||||
"message": "marked a checklist item as incomplete",
|
||||
"placeholders": {},
|
||||
@@ -3612,6 +3784,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 258]],
|
||||
"translation": "a marqué l'élément de checklist <0>{0}</0> comme incomplet"
|
||||
},
|
||||
"vo2a+a": {
|
||||
"translation": "Marketing",
|
||||
"message": "Marketing",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"agPptk": {
|
||||
"message": "Medium",
|
||||
"placeholders": {},
|
||||
@@ -3683,6 +3862,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 62],
|
||||
["src/views/pricing/components/Pricing.tsx", 14],
|
||||
["src/views/pricing/index.tsx", 20]
|
||||
],
|
||||
@@ -3695,6 +3875,20 @@
|
||||
"origin": [["src/views/members/components/InviteMemberForm.tsx", 159]],
|
||||
"translation": "facturation mensuelle"
|
||||
},
|
||||
"51UCsN": {
|
||||
"message": "Move to another list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 44]],
|
||||
"translation": "Déplacer vers une autre liste"
|
||||
},
|
||||
"J4+OTA": {
|
||||
"message": "Move to list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 70]],
|
||||
"translation": "Déplacer vers la liste"
|
||||
},
|
||||
"BOqTi5": {
|
||||
"message": "moved the card from <0>{0}</0> to<1>{1}</1>",
|
||||
"placeholders": {
|
||||
@@ -3806,7 +4000,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewListForm.tsx", 113],
|
||||
["src/views/board/index.tsx", 503]
|
||||
["src/views/board/index.tsx", 619]
|
||||
],
|
||||
"translation": "Nouvelle liste"
|
||||
},
|
||||
@@ -3932,14 +4126,14 @@
|
||||
"message": "No lists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 535]],
|
||||
"origin": [["src/views/board/index.tsx", 651]],
|
||||
"translation": "Aucune liste"
|
||||
},
|
||||
"fvLNDy": {
|
||||
"message": "No lists have been created yet",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 540]],
|
||||
"origin": [["src/views/board/index.tsx", 656]],
|
||||
"translation": "Aucune liste n'a encore été créée"
|
||||
},
|
||||
"i30J2U": {
|
||||
@@ -4020,7 +4214,7 @@
|
||||
"message": "Open command menu",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 31]],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 34]],
|
||||
"translation": "Ouvrir le menu de commandes"
|
||||
},
|
||||
"cFQEU/": {
|
||||
@@ -4236,6 +4430,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 86]],
|
||||
"translation": "Projet personnel"
|
||||
},
|
||||
"Oi+J+N": {
|
||||
"translation": "Choisissez un forfait pour commencer. Tous les forfaits payants incluent un essai gratuit de 14 jours.",
|
||||
"message": "Pick a plan to get started. All paid plans include a 14-day free trial.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 125]]
|
||||
},
|
||||
"Iqh0Uv": {
|
||||
"message": "Planned",
|
||||
"placeholders": {},
|
||||
@@ -4331,8 +4532,8 @@
|
||||
["src/views/board/components/NewTemplateForm.tsx", 77],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 73],
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 194],
|
||||
["src/views/board/index.tsx", 250],
|
||||
["src/views/board/index.tsx", 217],
|
||||
["src/views/board/index.tsx", 273],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
@@ -4360,6 +4561,8 @@
|
||||
["src/views/members/components/InviteMemberForm.tsx", 104],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 241],
|
||||
["src/views/members/index.tsx", 66],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 101],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 150],
|
||||
["src/views/settings/components/Avatar.tsx", 200],
|
||||
["src/views/settings/components/DeleteAccountConfirmation.tsx", 40],
|
||||
["src/views/settings/components/DeleteWorkspaceConfirmation.tsx", 46],
|
||||
@@ -4387,12 +4590,24 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 76],
|
||||
["src/views/board/components/CardContextMoveListModal.tsx", 42],
|
||||
["src/views/board/index.tsx", 314],
|
||||
["src/views/card/components/Dropdown.tsx", 51],
|
||||
["src/views/public/board/CardModal.tsx", 45],
|
||||
["src/views/public/board/index.tsx", 86]
|
||||
],
|
||||
"translation": "Veuillez réessayer."
|
||||
},
|
||||
"nYNMZZ": {
|
||||
"message": "Position in list (0 = first, leave empty for end)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 193]
|
||||
],
|
||||
"translation": "Position dans la liste (0 = premier, laisser vide pour la fin)"
|
||||
},
|
||||
"aHCEmh": {
|
||||
"message": "Pricing",
|
||||
"placeholders": {},
|
||||
@@ -4438,6 +4653,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 91],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 333],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 70]
|
||||
],
|
||||
@@ -4695,7 +4911,8 @@
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 36],
|
||||
["src/views/home/components/Header.tsx", 13],
|
||||
["src/views/home/components/Header.tsx", 28]
|
||||
["src/views/home/components/Header.tsx", 28],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 161]
|
||||
],
|
||||
"translation": "Roadmap"
|
||||
},
|
||||
@@ -4814,6 +5031,15 @@
|
||||
"origin": [["src/views/home/components/Testimonials.tsx", 239]],
|
||||
"translation": "Découvrez ce que nos utilisateurs disent de Kan"
|
||||
},
|
||||
"zYRVNp": {
|
||||
"message": "Select a list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 131]
|
||||
],
|
||||
"translation": "Sélectionner une liste"
|
||||
},
|
||||
"wgNoIs": {
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
@@ -4884,7 +5110,11 @@
|
||||
"message": "Set due date",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/DueDateSelector.tsx", 121]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 20],
|
||||
["src/views/board/components/CardContextMenu.tsx", 56],
|
||||
["src/views/card/components/DueDateSelector.tsx", 121]
|
||||
],
|
||||
"translation": "Définir la date d'échéance"
|
||||
},
|
||||
"Eit43O": {
|
||||
@@ -4894,6 +5124,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 142]],
|
||||
"translation": "a défini la date d'échéance"
|
||||
},
|
||||
"JjEJSy": {
|
||||
"translation": "Configurer votre espace de travail",
|
||||
"message": "Set up your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 179]]
|
||||
},
|
||||
"Tz0i8g": {
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
@@ -4974,6 +5211,16 @@
|
||||
"origin": [["src/views/invite/index.tsx", 154]],
|
||||
"translation": "Se connecter"
|
||||
},
|
||||
"fcWrnU": {
|
||||
"translation": "Se déconnecter",
|
||||
"message": "Sign out",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 284],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 362]
|
||||
]
|
||||
},
|
||||
"mErq7F": {
|
||||
"message": "Sign Up",
|
||||
"placeholders": {},
|
||||
@@ -5059,6 +5306,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 22]],
|
||||
"translation": "Développement logiciel"
|
||||
},
|
||||
"6sKjjx": {
|
||||
"translation": "Solo",
|
||||
"message": "Solo",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 76]]
|
||||
},
|
||||
"vnS6Rf": {
|
||||
"message": "SSO",
|
||||
"placeholders": {},
|
||||
@@ -5158,6 +5412,13 @@
|
||||
"origin": [["src/components/UserMenu.tsx", 144]],
|
||||
"translation": "Système"
|
||||
},
|
||||
"KM6m8p": {
|
||||
"translation": "Équipe",
|
||||
"message": "Team",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 83]]
|
||||
},
|
||||
"bff61F": {
|
||||
"message": "Team Plan",
|
||||
"placeholders": {},
|
||||
@@ -5184,8 +5445,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 449]
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/board/index.tsx", 565]
|
||||
],
|
||||
"translation": "Modèle"
|
||||
},
|
||||
@@ -5279,6 +5540,15 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Le tableau a été désarchivé."
|
||||
},
|
||||
"nKBUeF": {
|
||||
"message": "The card has been duplicated.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 69]
|
||||
],
|
||||
"translation": "La carte a été dupliquée."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5401,6 +5671,20 @@
|
||||
],
|
||||
"translation": "Les permissions de ce membre ont été réinitialisées aux valeurs par défaut de son rôle."
|
||||
},
|
||||
"HQVm6e": {
|
||||
"translation": "Cette URL est déjà prise",
|
||||
"message": "This URL has already been taken",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 73]]
|
||||
},
|
||||
"gKmoow": {
|
||||
"translation": "Cette URL est réservée",
|
||||
"message": "This URL is reserved",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 75]]
|
||||
},
|
||||
"OAYToL": {
|
||||
"message": "This will remove all custom member permissions in this workspace. Members will inherit permissions only from their roles.",
|
||||
"placeholders": {},
|
||||
@@ -5461,6 +5745,15 @@
|
||||
"origin": [["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 127]],
|
||||
"translation": "Titre"
|
||||
},
|
||||
"wK4OTM": {
|
||||
"message": "Title (optional)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 180]
|
||||
],
|
||||
"translation": "Titre (facultatif)"
|
||||
},
|
||||
"Se/UIp": {
|
||||
"message": "To Do",
|
||||
"placeholders": {},
|
||||
@@ -5563,6 +5856,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 312],
|
||||
["src/views/card/components/Dropdown.tsx", 49],
|
||||
["src/views/public/board/CardModal.tsx", 43],
|
||||
["src/views/public/board/index.tsx", 84]
|
||||
@@ -5604,7 +5898,10 @@
|
||||
"message": "Unable to create workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 158]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 100]
|
||||
],
|
||||
"translation": "Impossible de créer l'espace de travail"
|
||||
},
|
||||
"WHHLh9": {
|
||||
@@ -5644,6 +5941,22 @@
|
||||
"origin": [["src/views/card/components/DeleteCommentConfirmation.tsx", 45]],
|
||||
"translation": "Impossible de supprimer le commentaire"
|
||||
},
|
||||
"Oo4E6p": {
|
||||
"message": "Unable to duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 75]
|
||||
],
|
||||
"translation": "Impossible de dupliquer la carte"
|
||||
},
|
||||
"K7k9u3": {
|
||||
"message": "Unable to move card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 41]],
|
||||
"translation": "Impossible de déplacer la carte"
|
||||
},
|
||||
"8yFGGF": {
|
||||
"message": "Unable to remove member",
|
||||
"placeholders": {},
|
||||
@@ -5676,6 +5989,13 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 40]],
|
||||
"translation": "Impossible d'envoyer le feedback"
|
||||
},
|
||||
"Q60WUZ": {
|
||||
"translation": "Impossible de démarrer le paiement",
|
||||
"message": "Unable to start checkout",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 149]]
|
||||
},
|
||||
"T7Mywq": {
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
@@ -5702,7 +6022,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 249],
|
||||
["src/views/board/index.tsx", 272],
|
||||
["src/views/card/index.tsx", 231]
|
||||
],
|
||||
"translation": "Impossible de mettre à jour la carte"
|
||||
@@ -5747,7 +6067,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 193],
|
||||
["src/views/board/index.tsx", 216],
|
||||
["src/views/card/components/ListSelector.tsx", 54]
|
||||
],
|
||||
"translation": "Impossible de mettre à jour la liste"
|
||||
@@ -5883,6 +6203,13 @@
|
||||
],
|
||||
"translation": "Membres illimités"
|
||||
},
|
||||
"8AwlaR": {
|
||||
"translation": "Membres illimités et un nom d'utilisateur d'espace de travail personnalisé pour les équipes prêtes à évoluer.",
|
||||
"message": "Unlimited members and a custom workspace username for teams ready to scale.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 94]]
|
||||
},
|
||||
"Ws+3X+": {
|
||||
"message": "Unlimited seats and advanced features for growing teams.",
|
||||
"placeholders": {},
|
||||
@@ -5972,7 +6299,10 @@
|
||||
"message": "Upgrade to Pro ($29/month)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 373]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 373],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 243]
|
||||
],
|
||||
"translation": "Passer à Pro (29 $/mois)"
|
||||
},
|
||||
"b3Thhd": {
|
||||
@@ -6256,7 +6586,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 47],
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
@@ -6284,7 +6614,10 @@
|
||||
"message": "Workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 82]],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 253],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 82]
|
||||
],
|
||||
"translation": "Description de l'espace de travail"
|
||||
},
|
||||
"Ax/hYa": {
|
||||
@@ -6331,6 +6664,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 263],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 188],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 63]
|
||||
],
|
||||
"translation": "Nom de l'espace de travail"
|
||||
@@ -6438,6 +6772,13 @@
|
||||
"origin": [["src/views/settings/AccountSettings.tsx", 91]],
|
||||
"translation": "Vous êtes sur le point de modifier votre mot de passe."
|
||||
},
|
||||
"3WXdoZ": {
|
||||
"translation": "Vous pourrez toujours modifier ces paramètres plus tard dans les réglages.",
|
||||
"message": "You can always change these later in settings.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 182]]
|
||||
},
|
||||
"aelko+": {
|
||||
"message": "You can get a custom workspace URL, like <0>kan.bn/kan</0>, by going into your <1>workspace settings</1> and purchasing a pro workspace subscription. All subscriptions help fund the development of the project!",
|
||||
"placeholders": {},
|
||||
@@ -6467,8 +6808,8 @@
|
||||
["src/views/board/components/List.tsx", 117],
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 58],
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 487],
|
||||
["src/views/board/index.tsx", 545],
|
||||
["src/views/board/index.tsx", 603],
|
||||
["src/views/board/index.tsx", 661],
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
@@ -6533,6 +6874,13 @@
|
||||
],
|
||||
"translation": "Votre compte a été supprimé."
|
||||
},
|
||||
"c4nMcR": {
|
||||
"translation": "Votre avatar",
|
||||
"message": "Your avatar",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 229]]
|
||||
},
|
||||
"evg7+A": {
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
@@ -6619,6 +6967,20 @@
|
||||
"origin": [["src/pages/unsubscribe/index.tsx", 33]],
|
||||
"translation": "Votre lien de désinscription ne contient pas de jeton. Veuillez ouvrir le dernier e-mail et réessayer."
|
||||
},
|
||||
"GRAGsB": {
|
||||
"translation": "Votre espace de travail",
|
||||
"message": "Your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 322]]
|
||||
},
|
||||
"j0o6ml": {
|
||||
"translation": "La description de votre espace de travail",
|
||||
"message": "Your workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 325]]
|
||||
},
|
||||
"GnSSGm": {
|
||||
"message": "Your workspace description has been updated.",
|
||||
"placeholders": {},
|
||||
@@ -6655,6 +7017,16 @@
|
||||
],
|
||||
"translation": "L'identifiant de votre espace de travail a été mis à jour."
|
||||
},
|
||||
"OTxjpR": {
|
||||
"translation": "votre-espace-de-travail",
|
||||
"message": "your-workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 197],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 198]
|
||||
]
|
||||
},
|
||||
"4DOCMI": {
|
||||
"message": "YouTube URL",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -71,7 +71,7 @@
|
||||
"0": ["isTemplate ? \"Template\" : \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 440]],
|
||||
"origin": [["src/views/board/index.tsx", 556]],
|
||||
"translation": "{0} non trovato"
|
||||
},
|
||||
"0xWkkH": {
|
||||
@@ -238,6 +238,13 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 110]],
|
||||
"translation": "Registri attività"
|
||||
},
|
||||
"UGCIzB": {
|
||||
"message": "Add / edit label",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 50]],
|
||||
"translation": "Aggiungi / modifica etichetta"
|
||||
},
|
||||
"B3xxao": {
|
||||
"message": "Add a card",
|
||||
"placeholders": {},
|
||||
@@ -288,8 +295,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/LabelSelector.tsx", 113],
|
||||
["src/views/card/components/LabelSelector.tsx", 118]
|
||||
["src/views/card/components/LabelSelector.tsx", 114],
|
||||
["src/views/card/components/LabelSelector.tsx", 119]
|
||||
],
|
||||
"translation": "Aggiungi etichetta"
|
||||
},
|
||||
@@ -298,7 +305,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 134],
|
||||
["src/views/card/components/MemberSelector.tsx", 135],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 257]
|
||||
],
|
||||
"translation": "Aggiungi membro"
|
||||
@@ -549,6 +556,13 @@
|
||||
],
|
||||
"translation": "Si è verificato un errore imprevisto. Riprova più tardi."
|
||||
},
|
||||
"YkfDoz": {
|
||||
"translation": "Annuale",
|
||||
"message": "Annual",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 63]]
|
||||
},
|
||||
"3bqt9U": {
|
||||
"message": "Anyone with this link can join your workspace",
|
||||
"placeholders": {},
|
||||
@@ -749,6 +763,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 59]],
|
||||
"translation": "In attesa del cliente"
|
||||
},
|
||||
"iH8pgl": {
|
||||
"translation": "Indietro",
|
||||
"message": "Back",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 275]]
|
||||
},
|
||||
"KNKCTb": {
|
||||
"message": "Backlog",
|
||||
"placeholders": {},
|
||||
@@ -791,6 +812,13 @@
|
||||
"origin": [["src/views/pricing/components/PricingTiers.tsx", 53]],
|
||||
"translation": "Ideale per piccoli team in crescita che necessitano di collaborazione"
|
||||
},
|
||||
"zt/6cS": {
|
||||
"translation": "Ideale per piccoli team che vogliono collaborare e muoversi più velocemente insieme.",
|
||||
"message": "Best for small teams who want to collaborate and move faster together.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 86]]
|
||||
},
|
||||
"qaS+1/": {
|
||||
"message": "Best for teams that want to scale without limits",
|
||||
"placeholders": {},
|
||||
@@ -842,7 +870,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/card/index.tsx", 317],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
@@ -1235,12 +1263,14 @@
|
||||
"origin": [
|
||||
["src/components/DeleteLabelConfirmation.tsx", 49],
|
||||
["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 176],
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 267],
|
||||
["src/views/board/components/DeleteBoardConfirmation.tsx", 44],
|
||||
["src/views/card/components/Comment.tsx", 195],
|
||||
["src/views/card/components/DeleteCardConfirmation.tsx", 86],
|
||||
["src/views/card/components/DeleteChecklistConfirmation.tsx", 64],
|
||||
["src/views/card/components/DeleteCommentConfirmation.tsx", 77],
|
||||
["src/views/members/components/DeleteMemberConfirmation.tsx", 55],
|
||||
["src/views/onboarding/select-plan/index.tsx", 209],
|
||||
["src/views/settings/components/Avatar.tsx", 287],
|
||||
["src/views/settings/components/ChangePasswordConfirmation.tsx", 168],
|
||||
[
|
||||
@@ -1261,6 +1291,15 @@
|
||||
"origin": [["src/views/card/index.tsx", 317]],
|
||||
"translation": "Card"
|
||||
},
|
||||
"sU2uWc": {
|
||||
"message": "Card duplicated",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 67]
|
||||
],
|
||||
"translation": "Scheda duplicata"
|
||||
},
|
||||
"fEY2vP": {
|
||||
"message": "Card not found",
|
||||
"placeholders": {},
|
||||
@@ -1283,6 +1322,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 307],
|
||||
["src/views/card/components/Dropdown.tsx", 44],
|
||||
["src/views/public/board/CardModal.tsx", 38]
|
||||
],
|
||||
@@ -1360,6 +1400,13 @@
|
||||
],
|
||||
"translation": "Checklist"
|
||||
},
|
||||
"zMquA7": {
|
||||
"translation": "Scegli un piano",
|
||||
"message": "Choose a plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 122]]
|
||||
},
|
||||
"VHS0aJ": {
|
||||
"message": "Clear all custom permissions?",
|
||||
"placeholders": {},
|
||||
@@ -1617,6 +1664,16 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 40]],
|
||||
"translation": "Creazione di contenuti"
|
||||
},
|
||||
"xGVfLh": {
|
||||
"translation": "Continua",
|
||||
"message": "Continue",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 212],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 291]
|
||||
]
|
||||
},
|
||||
"J2Wbjt": {
|
||||
"message": "Continue with ",
|
||||
"placeholders": {},
|
||||
@@ -1661,6 +1718,40 @@
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 58]],
|
||||
"translation": "Copia link card"
|
||||
},
|
||||
"0utuU6": {
|
||||
"message": "Copy checklists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 257]
|
||||
],
|
||||
"translation": "Copia checklist"
|
||||
},
|
||||
"fDQ7hA": {
|
||||
"message": "Copy labels",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 221]
|
||||
],
|
||||
"translation": "Copia etichette"
|
||||
},
|
||||
"1bJKhj": {
|
||||
"message": "Copy link to card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 62]],
|
||||
"translation": "Copia link alla scheda"
|
||||
},
|
||||
"uvH2xS": {
|
||||
"message": "Copy members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 239]
|
||||
],
|
||||
"translation": "Copia membri"
|
||||
},
|
||||
"9PaIxv": {
|
||||
"message": "Core features",
|
||||
"placeholders": {},
|
||||
@@ -1757,7 +1848,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewCardForm.tsx", 417],
|
||||
["src/views/card/components/LabelSelector.tsx", 100]
|
||||
["src/views/card/components/LabelSelector.tsx", 101]
|
||||
],
|
||||
"translation": "Crea nuova etichetta"
|
||||
},
|
||||
@@ -1766,8 +1857,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 76],
|
||||
["src/views/board/index.tsx", 554]
|
||||
["src/views/board/index.tsx", 91],
|
||||
["src/views/board/index.tsx", 670]
|
||||
],
|
||||
"translation": "Crea nuova lista"
|
||||
},
|
||||
@@ -1791,7 +1882,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 388],
|
||||
["src/components/WorkspaceMenu.tsx", 153]
|
||||
["src/components/WorkspaceMenu.tsx", 160]
|
||||
],
|
||||
"translation": "Crea workspace"
|
||||
},
|
||||
@@ -1891,6 +1982,13 @@
|
||||
],
|
||||
"translation": "Username personalizzato"
|
||||
},
|
||||
"ZDPJBc": {
|
||||
"translation": "I nomi utente personalizzati richiedono l'aggiornamento a un piano Pro",
|
||||
"message": "Custom usernames require upgrading to a Pro plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 220]]
|
||||
},
|
||||
"j9IZZ0": {
|
||||
"message": "Custom workspace URL",
|
||||
"placeholders": {},
|
||||
@@ -1985,7 +2083,10 @@
|
||||
"message": "Delete card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 76]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMenu.tsx", 74],
|
||||
["src/views/card/components/Dropdown.tsx", 76]
|
||||
],
|
||||
"translation": "Elimina card"
|
||||
},
|
||||
"njJFtc": {
|
||||
@@ -2171,6 +2272,9 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 36],
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 48],
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 68],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 17],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 23],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 29],
|
||||
@@ -2226,6 +2330,34 @@
|
||||
"origin": [["src/views/board/components/Filters.tsx", 122]],
|
||||
"translation": "Scadenza domani"
|
||||
},
|
||||
"euc6Ns": {
|
||||
"message": "Duplicate",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplica"
|
||||
},
|
||||
"BTDPLo": {
|
||||
"message": "Duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 111],
|
||||
["src/views/board/components/CardContextMenu.tsx", 68]
|
||||
],
|
||||
"translation": "Duplica scheda"
|
||||
},
|
||||
"06EQqT": {
|
||||
"message": "Duplicating…",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplicazione in corso…"
|
||||
},
|
||||
"ePK91l": {
|
||||
"message": "Edit",
|
||||
"placeholders": {},
|
||||
@@ -2338,6 +2470,22 @@
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 100]],
|
||||
"translation": "Visibilità email"
|
||||
},
|
||||
"bFREhu": {
|
||||
"message": "End of list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 200]
|
||||
],
|
||||
"translation": "Fine dell'elenco"
|
||||
},
|
||||
"SUXBxp": {
|
||||
"translation": "Ingegneria",
|
||||
"message": "Engineering",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"0+ewPp": {
|
||||
"message": "Enhancement",
|
||||
"placeholders": {},
|
||||
@@ -2794,6 +2942,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 77],
|
||||
["src/views/onboarding/select-plan/index.tsx", 78],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 331],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
@@ -2894,7 +3044,7 @@
|
||||
"message": "Get started by creating a new list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 539]],
|
||||
"origin": [["src/views/board/index.tsx", 655]],
|
||||
"translation": "Inizia creando una nuova lista"
|
||||
},
|
||||
"oW13KZ": {
|
||||
@@ -3004,6 +3154,13 @@
|
||||
"origin": [["src/components/SideNavigation.tsx", 119]],
|
||||
"translation": "Vai ai modelli"
|
||||
},
|
||||
"SUvm1Y": {
|
||||
"translation": "Perfetto per chi inizia e ha bisogno solo delle funzionalità essenziali.",
|
||||
"message": "Good for individuals starting out who just need the essentials.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 79]]
|
||||
},
|
||||
"cdyS7J": {
|
||||
"message": "Google SSO",
|
||||
"placeholders": {},
|
||||
@@ -3314,7 +3471,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 114],
|
||||
["src/views/card/components/MemberSelector.tsx", 115],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 367]
|
||||
],
|
||||
"translation": "Invita membro"
|
||||
@@ -3386,6 +3543,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 31],
|
||||
["src/views/board/components/Filters.tsx", 155],
|
||||
["src/views/board/components/NewCardForm.tsx", 421],
|
||||
["src/views/card/index.tsx", 133]
|
||||
@@ -3497,6 +3655,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 80],
|
||||
["src/views/board/index.tsx", 305],
|
||||
["src/views/card/components/Dropdown.tsx", 42],
|
||||
["src/views/public/board/CardModal.tsx", 36],
|
||||
["src/views/public/board/index.tsx", 77]
|
||||
@@ -3507,7 +3666,10 @@
|
||||
"message": "List",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 124]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 117],
|
||||
["src/views/card/index.tsx", 124]
|
||||
],
|
||||
"translation": "Lista"
|
||||
},
|
||||
"zQX5Dj": {
|
||||
@@ -3596,6 +3758,16 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Crea template"
|
||||
},
|
||||
"hB02vO": {
|
||||
"message": "Manage members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 51],
|
||||
["src/views/board/components/CardContextMenu.tsx", 38]
|
||||
],
|
||||
"translation": "Gestisci membri"
|
||||
},
|
||||
"IDvohQ": {
|
||||
"message": "marked a checklist item as incomplete",
|
||||
"placeholders": {},
|
||||
@@ -3612,6 +3784,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 258]],
|
||||
"translation": "ha contrassegnato l'elemento della checklist <0>{0}</0> come incompleto"
|
||||
},
|
||||
"vo2a+a": {
|
||||
"translation": "Marketing",
|
||||
"message": "Marketing",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"agPptk": {
|
||||
"message": "Medium",
|
||||
"placeholders": {},
|
||||
@@ -3683,6 +3862,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 62],
|
||||
["src/views/pricing/components/Pricing.tsx", 14],
|
||||
["src/views/pricing/index.tsx", 20]
|
||||
],
|
||||
@@ -3695,6 +3875,20 @@
|
||||
"origin": [["src/views/members/components/InviteMemberForm.tsx", 159]],
|
||||
"translation": "fatturazione mensile"
|
||||
},
|
||||
"51UCsN": {
|
||||
"message": "Move to another list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 44]],
|
||||
"translation": "Sposta in un altro elenco"
|
||||
},
|
||||
"J4+OTA": {
|
||||
"message": "Move to list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 70]],
|
||||
"translation": "Sposta nell'elenco"
|
||||
},
|
||||
"BOqTi5": {
|
||||
"message": "moved the card from <0>{0}</0> to<1>{1}</1>",
|
||||
"placeholders": {
|
||||
@@ -3806,7 +4000,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewListForm.tsx", 113],
|
||||
["src/views/board/index.tsx", 503]
|
||||
["src/views/board/index.tsx", 619]
|
||||
],
|
||||
"translation": "Nuova lista"
|
||||
},
|
||||
@@ -3932,14 +4126,14 @@
|
||||
"message": "No lists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 535]],
|
||||
"origin": [["src/views/board/index.tsx", 651]],
|
||||
"translation": "Nessuna lista"
|
||||
},
|
||||
"fvLNDy": {
|
||||
"message": "No lists have been created yet",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 540]],
|
||||
"origin": [["src/views/board/index.tsx", 656]],
|
||||
"translation": "Nessuna lista è stata ancora creata"
|
||||
},
|
||||
"i30J2U": {
|
||||
@@ -4020,7 +4214,7 @@
|
||||
"message": "Open command menu",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 31]],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 34]],
|
||||
"translation": "Apri menu comandi"
|
||||
},
|
||||
"cFQEU/": {
|
||||
@@ -4236,6 +4430,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 86]],
|
||||
"translation": "Progetto personale"
|
||||
},
|
||||
"Oi+J+N": {
|
||||
"translation": "Scegli un piano per iniziare. Tutti i piani a pagamento includono una prova gratuita di 14 giorni.",
|
||||
"message": "Pick a plan to get started. All paid plans include a 14-day free trial.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 125]]
|
||||
},
|
||||
"Iqh0Uv": {
|
||||
"message": "Planned",
|
||||
"placeholders": {},
|
||||
@@ -4331,8 +4532,8 @@
|
||||
["src/views/board/components/NewTemplateForm.tsx", 77],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 73],
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 194],
|
||||
["src/views/board/index.tsx", 250],
|
||||
["src/views/board/index.tsx", 217],
|
||||
["src/views/board/index.tsx", 273],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
@@ -4360,6 +4561,8 @@
|
||||
["src/views/members/components/InviteMemberForm.tsx", 104],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 241],
|
||||
["src/views/members/index.tsx", 66],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 101],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 150],
|
||||
["src/views/settings/components/Avatar.tsx", 200],
|
||||
["src/views/settings/components/DeleteAccountConfirmation.tsx", 40],
|
||||
["src/views/settings/components/DeleteWorkspaceConfirmation.tsx", 46],
|
||||
@@ -4387,12 +4590,24 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 76],
|
||||
["src/views/board/components/CardContextMoveListModal.tsx", 42],
|
||||
["src/views/board/index.tsx", 314],
|
||||
["src/views/card/components/Dropdown.tsx", 51],
|
||||
["src/views/public/board/CardModal.tsx", 45],
|
||||
["src/views/public/board/index.tsx", 86]
|
||||
],
|
||||
"translation": "Riprova."
|
||||
},
|
||||
"nYNMZZ": {
|
||||
"message": "Position in list (0 = first, leave empty for end)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 193]
|
||||
],
|
||||
"translation": "Posizione nell'elenco (0 = primo, lascia vuoto per la fine)"
|
||||
},
|
||||
"aHCEmh": {
|
||||
"message": "Pricing",
|
||||
"placeholders": {},
|
||||
@@ -4438,6 +4653,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 91],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 333],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 70]
|
||||
],
|
||||
@@ -4695,7 +4911,8 @@
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 36],
|
||||
["src/views/home/components/Header.tsx", 13],
|
||||
["src/views/home/components/Header.tsx", 28]
|
||||
["src/views/home/components/Header.tsx", 28],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 161]
|
||||
],
|
||||
"translation": "Roadmap"
|
||||
},
|
||||
@@ -4814,6 +5031,15 @@
|
||||
"origin": [["src/views/home/components/Testimonials.tsx", 239]],
|
||||
"translation": "Scopri cosa dicono i nostri utenti su Kan"
|
||||
},
|
||||
"zYRVNp": {
|
||||
"message": "Select a list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 131]
|
||||
],
|
||||
"translation": "Seleziona un elenco"
|
||||
},
|
||||
"wgNoIs": {
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
@@ -4884,7 +5110,11 @@
|
||||
"message": "Set due date",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/DueDateSelector.tsx", 121]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 20],
|
||||
["src/views/board/components/CardContextMenu.tsx", 56],
|
||||
["src/views/card/components/DueDateSelector.tsx", 121]
|
||||
],
|
||||
"translation": "Imposta scadenza"
|
||||
},
|
||||
"Eit43O": {
|
||||
@@ -4894,6 +5124,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 142]],
|
||||
"translation": "ha impostato la scadenza"
|
||||
},
|
||||
"JjEJSy": {
|
||||
"translation": "Configura il tuo workspace",
|
||||
"message": "Set up your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 179]]
|
||||
},
|
||||
"Tz0i8g": {
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
@@ -4974,6 +5211,16 @@
|
||||
"origin": [["src/views/invite/index.tsx", 154]],
|
||||
"translation": "Accedi"
|
||||
},
|
||||
"fcWrnU": {
|
||||
"translation": "Esci",
|
||||
"message": "Sign out",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 284],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 362]
|
||||
]
|
||||
},
|
||||
"mErq7F": {
|
||||
"message": "Sign Up",
|
||||
"placeholders": {},
|
||||
@@ -5059,6 +5306,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 22]],
|
||||
"translation": "Sviluppo software"
|
||||
},
|
||||
"6sKjjx": {
|
||||
"translation": "Solo",
|
||||
"message": "Solo",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 76]]
|
||||
},
|
||||
"vnS6Rf": {
|
||||
"message": "SSO",
|
||||
"placeholders": {},
|
||||
@@ -5158,6 +5412,13 @@
|
||||
"origin": [["src/components/UserMenu.tsx", 144]],
|
||||
"translation": "Sistema"
|
||||
},
|
||||
"KM6m8p": {
|
||||
"translation": "Team",
|
||||
"message": "Team",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 83]]
|
||||
},
|
||||
"bff61F": {
|
||||
"message": "Team Plan",
|
||||
"placeholders": {},
|
||||
@@ -5184,8 +5445,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 449]
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/board/index.tsx", 565]
|
||||
],
|
||||
"translation": "Template"
|
||||
},
|
||||
@@ -5279,6 +5540,15 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "La bacheca è stata ripristinata."
|
||||
},
|
||||
"nKBUeF": {
|
||||
"message": "The card has been duplicated.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 69]
|
||||
],
|
||||
"translation": "La scheda è stata duplicata."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5401,6 +5671,20 @@
|
||||
],
|
||||
"translation": "I permessi di questo membro sono stati ripristinati ai valori predefiniti del suo ruolo."
|
||||
},
|
||||
"HQVm6e": {
|
||||
"translation": "Questo URL è già in uso",
|
||||
"message": "This URL has already been taken",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 73]]
|
||||
},
|
||||
"gKmoow": {
|
||||
"translation": "Questo URL è riservato",
|
||||
"message": "This URL is reserved",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 75]]
|
||||
},
|
||||
"OAYToL": {
|
||||
"message": "This will remove all custom member permissions in this workspace. Members will inherit permissions only from their roles.",
|
||||
"placeholders": {},
|
||||
@@ -5461,6 +5745,15 @@
|
||||
"origin": [["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 127]],
|
||||
"translation": "Titolo"
|
||||
},
|
||||
"wK4OTM": {
|
||||
"message": "Title (optional)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 180]
|
||||
],
|
||||
"translation": "Titolo (facoltativo)"
|
||||
},
|
||||
"Se/UIp": {
|
||||
"message": "To Do",
|
||||
"placeholders": {},
|
||||
@@ -5563,6 +5856,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 312],
|
||||
["src/views/card/components/Dropdown.tsx", 49],
|
||||
["src/views/public/board/CardModal.tsx", 43],
|
||||
["src/views/public/board/index.tsx", 84]
|
||||
@@ -5604,7 +5898,10 @@
|
||||
"message": "Unable to create workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 158]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 100]
|
||||
],
|
||||
"translation": "Impossibile creare lo workspace"
|
||||
},
|
||||
"WHHLh9": {
|
||||
@@ -5644,6 +5941,22 @@
|
||||
"origin": [["src/views/card/components/DeleteCommentConfirmation.tsx", 45]],
|
||||
"translation": "Impossibile eliminare il commento"
|
||||
},
|
||||
"Oo4E6p": {
|
||||
"message": "Unable to duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 75]
|
||||
],
|
||||
"translation": "Impossibile duplicare la scheda"
|
||||
},
|
||||
"K7k9u3": {
|
||||
"message": "Unable to move card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 41]],
|
||||
"translation": "Impossibile spostare la scheda"
|
||||
},
|
||||
"8yFGGF": {
|
||||
"message": "Unable to remove member",
|
||||
"placeholders": {},
|
||||
@@ -5676,6 +5989,13 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 40]],
|
||||
"translation": "Impossibile inviare il feedback"
|
||||
},
|
||||
"Q60WUZ": {
|
||||
"translation": "Impossibile avviare il checkout",
|
||||
"message": "Unable to start checkout",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 149]]
|
||||
},
|
||||
"T7Mywq": {
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
@@ -5702,7 +6022,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 249],
|
||||
["src/views/board/index.tsx", 272],
|
||||
["src/views/card/index.tsx", 231]
|
||||
],
|
||||
"translation": "Impossibile aggiornare la card"
|
||||
@@ -5747,7 +6067,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 193],
|
||||
["src/views/board/index.tsx", 216],
|
||||
["src/views/card/components/ListSelector.tsx", 54]
|
||||
],
|
||||
"translation": "Impossibile aggiornare la lista"
|
||||
@@ -5883,6 +6203,13 @@
|
||||
],
|
||||
"translation": "Membri illimitati"
|
||||
},
|
||||
"8AwlaR": {
|
||||
"translation": "Membri illimitati e un nome utente workspace personalizzato per i team pronti a crescere.",
|
||||
"message": "Unlimited members and a custom workspace username for teams ready to scale.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 94]]
|
||||
},
|
||||
"Ws+3X+": {
|
||||
"message": "Unlimited seats and advanced features for growing teams.",
|
||||
"placeholders": {},
|
||||
@@ -5972,7 +6299,10 @@
|
||||
"message": "Upgrade to Pro ($29/month)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 373]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 373],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 243]
|
||||
],
|
||||
"translation": "Passa a Pro ($29/mese)"
|
||||
},
|
||||
"b3Thhd": {
|
||||
@@ -6256,7 +6586,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 47],
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
@@ -6284,7 +6614,10 @@
|
||||
"message": "Workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 82]],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 253],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 82]
|
||||
],
|
||||
"translation": "Descrizione workspace"
|
||||
},
|
||||
"Ax/hYa": {
|
||||
@@ -6331,6 +6664,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 263],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 188],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 63]
|
||||
],
|
||||
"translation": "Nome workspace"
|
||||
@@ -6438,6 +6772,13 @@
|
||||
"origin": [["src/views/settings/AccountSettings.tsx", 91]],
|
||||
"translation": "Stai per modificare la tua password."
|
||||
},
|
||||
"3WXdoZ": {
|
||||
"translation": "Potrai sempre modificarli in seguito nelle impostazioni.",
|
||||
"message": "You can always change these later in settings.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 182]]
|
||||
},
|
||||
"aelko+": {
|
||||
"message": "You can get a custom workspace URL, like <0>kan.bn/kan</0>, by going into your <1>workspace settings</1> and purchasing a pro workspace subscription. All subscriptions help fund the development of the project!",
|
||||
"placeholders": {},
|
||||
@@ -6467,8 +6808,8 @@
|
||||
["src/views/board/components/List.tsx", 117],
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 58],
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 487],
|
||||
["src/views/board/index.tsx", 545],
|
||||
["src/views/board/index.tsx", 603],
|
||||
["src/views/board/index.tsx", 661],
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
@@ -6533,6 +6874,13 @@
|
||||
],
|
||||
"translation": "Il tuo account è stato eliminato."
|
||||
},
|
||||
"c4nMcR": {
|
||||
"translation": "Il tuo avatar",
|
||||
"message": "Your avatar",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 229]]
|
||||
},
|
||||
"evg7+A": {
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
@@ -6619,6 +6967,20 @@
|
||||
"origin": [["src/pages/unsubscribe/index.tsx", 33]],
|
||||
"translation": "Il tuo link di disiscrizione non contiene un token. Apri l'ultima email e riprova."
|
||||
},
|
||||
"GRAGsB": {
|
||||
"translation": "Il tuo workspace",
|
||||
"message": "Your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 322]]
|
||||
},
|
||||
"j0o6ml": {
|
||||
"translation": "La descrizione del tuo workspace",
|
||||
"message": "Your workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 325]]
|
||||
},
|
||||
"GnSSGm": {
|
||||
"message": "Your workspace description has been updated.",
|
||||
"placeholders": {},
|
||||
@@ -6655,6 +7017,16 @@
|
||||
],
|
||||
"translation": "Lo slug del tuo workspace è stato aggiornato."
|
||||
},
|
||||
"OTxjpR": {
|
||||
"translation": "il-tuo-workspace",
|
||||
"message": "your-workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 197],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 198]
|
||||
]
|
||||
},
|
||||
"4DOCMI": {
|
||||
"message": "YouTube URL",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -71,7 +71,7 @@
|
||||
"0": ["isTemplate ? \"Template\" : \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 440]],
|
||||
"origin": [["src/views/board/index.tsx", 556]],
|
||||
"translation": "{0} niet gevonden"
|
||||
},
|
||||
"0xWkkH": {
|
||||
@@ -238,6 +238,13 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 110]],
|
||||
"translation": "Activiteitenlogboeken"
|
||||
},
|
||||
"UGCIzB": {
|
||||
"message": "Add / edit label",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 50]],
|
||||
"translation": "Label toevoegen / bewerken"
|
||||
},
|
||||
"B3xxao": {
|
||||
"message": "Add a card",
|
||||
"placeholders": {},
|
||||
@@ -288,8 +295,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/LabelSelector.tsx", 113],
|
||||
["src/views/card/components/LabelSelector.tsx", 118]
|
||||
["src/views/card/components/LabelSelector.tsx", 114],
|
||||
["src/views/card/components/LabelSelector.tsx", 119]
|
||||
],
|
||||
"translation": "Label toevoegen"
|
||||
},
|
||||
@@ -298,7 +305,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 134],
|
||||
["src/views/card/components/MemberSelector.tsx", 135],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 257]
|
||||
],
|
||||
"translation": "Lid toevoegen"
|
||||
@@ -549,6 +556,13 @@
|
||||
],
|
||||
"translation": "Er is een onverwachte fout opgetreden. Probeer het later opnieuw."
|
||||
},
|
||||
"YkfDoz": {
|
||||
"translation": "Jaarlijks",
|
||||
"message": "Annual",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 63]]
|
||||
},
|
||||
"3bqt9U": {
|
||||
"message": "Anyone with this link can join your workspace",
|
||||
"placeholders": {},
|
||||
@@ -749,6 +763,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 59]],
|
||||
"translation": "Wacht op klant"
|
||||
},
|
||||
"iH8pgl": {
|
||||
"translation": "Terug",
|
||||
"message": "Back",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 275]]
|
||||
},
|
||||
"KNKCTb": {
|
||||
"message": "Backlog",
|
||||
"placeholders": {},
|
||||
@@ -791,6 +812,13 @@
|
||||
"origin": [["src/views/pricing/components/PricingTiers.tsx", 53]],
|
||||
"translation": "Het beste voor kleine en groeiende teams die samenwerking nodig hebben"
|
||||
},
|
||||
"zt/6cS": {
|
||||
"translation": "Het beste voor kleine teams die willen samenwerken en sneller vooruit willen komen.",
|
||||
"message": "Best for small teams who want to collaborate and move faster together.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 86]]
|
||||
},
|
||||
"qaS+1/": {
|
||||
"message": "Best for teams that want to scale without limits",
|
||||
"placeholders": {},
|
||||
@@ -842,7 +870,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/card/index.tsx", 317],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
@@ -1235,12 +1263,14 @@
|
||||
"origin": [
|
||||
["src/components/DeleteLabelConfirmation.tsx", 49],
|
||||
["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 176],
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 267],
|
||||
["src/views/board/components/DeleteBoardConfirmation.tsx", 44],
|
||||
["src/views/card/components/Comment.tsx", 195],
|
||||
["src/views/card/components/DeleteCardConfirmation.tsx", 86],
|
||||
["src/views/card/components/DeleteChecklistConfirmation.tsx", 64],
|
||||
["src/views/card/components/DeleteCommentConfirmation.tsx", 77],
|
||||
["src/views/members/components/DeleteMemberConfirmation.tsx", 55],
|
||||
["src/views/onboarding/select-plan/index.tsx", 209],
|
||||
["src/views/settings/components/Avatar.tsx", 287],
|
||||
["src/views/settings/components/ChangePasswordConfirmation.tsx", 168],
|
||||
[
|
||||
@@ -1261,6 +1291,15 @@
|
||||
"origin": [["src/views/card/index.tsx", 317]],
|
||||
"translation": "Kaart"
|
||||
},
|
||||
"sU2uWc": {
|
||||
"message": "Card duplicated",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 67]
|
||||
],
|
||||
"translation": "Kaart gedupliceerd"
|
||||
},
|
||||
"fEY2vP": {
|
||||
"message": "Card not found",
|
||||
"placeholders": {},
|
||||
@@ -1283,6 +1322,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 307],
|
||||
["src/views/card/components/Dropdown.tsx", 44],
|
||||
["src/views/public/board/CardModal.tsx", 38]
|
||||
],
|
||||
@@ -1360,6 +1400,13 @@
|
||||
],
|
||||
"translation": "Checklists"
|
||||
},
|
||||
"zMquA7": {
|
||||
"translation": "Kies een abonnement",
|
||||
"message": "Choose a plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 122]]
|
||||
},
|
||||
"VHS0aJ": {
|
||||
"message": "Clear all custom permissions?",
|
||||
"placeholders": {},
|
||||
@@ -1617,6 +1664,16 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 40]],
|
||||
"translation": "Content creatie"
|
||||
},
|
||||
"xGVfLh": {
|
||||
"translation": "Doorgaan",
|
||||
"message": "Continue",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 212],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 291]
|
||||
]
|
||||
},
|
||||
"J2Wbjt": {
|
||||
"message": "Continue with ",
|
||||
"placeholders": {},
|
||||
@@ -1661,6 +1718,40 @@
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 58]],
|
||||
"translation": "Kopieer kaartlink"
|
||||
},
|
||||
"0utuU6": {
|
||||
"message": "Copy checklists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 257]
|
||||
],
|
||||
"translation": "Checklists kopiëren"
|
||||
},
|
||||
"fDQ7hA": {
|
||||
"message": "Copy labels",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 221]
|
||||
],
|
||||
"translation": "Labels kopiëren"
|
||||
},
|
||||
"1bJKhj": {
|
||||
"message": "Copy link to card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 62]],
|
||||
"translation": "Link naar kaart kopiëren"
|
||||
},
|
||||
"uvH2xS": {
|
||||
"message": "Copy members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 239]
|
||||
],
|
||||
"translation": "Leden kopiëren"
|
||||
},
|
||||
"9PaIxv": {
|
||||
"message": "Core features",
|
||||
"placeholders": {},
|
||||
@@ -1757,7 +1848,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewCardForm.tsx", 417],
|
||||
["src/views/card/components/LabelSelector.tsx", 100]
|
||||
["src/views/card/components/LabelSelector.tsx", 101]
|
||||
],
|
||||
"translation": "Maak nieuw label"
|
||||
},
|
||||
@@ -1766,8 +1857,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 76],
|
||||
["src/views/board/index.tsx", 554]
|
||||
["src/views/board/index.tsx", 91],
|
||||
["src/views/board/index.tsx", 670]
|
||||
],
|
||||
"translation": "Maak nieuwe lijst"
|
||||
},
|
||||
@@ -1791,7 +1882,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 388],
|
||||
["src/components/WorkspaceMenu.tsx", 153]
|
||||
["src/components/WorkspaceMenu.tsx", 160]
|
||||
],
|
||||
"translation": "Maak werkruimte"
|
||||
},
|
||||
@@ -1891,6 +1982,13 @@
|
||||
],
|
||||
"translation": "Aangepaste gebruikersnaam"
|
||||
},
|
||||
"ZDPJBc": {
|
||||
"translation": "Aangepaste gebruikersnamen vereisen een upgrade naar een Pro-abonnement",
|
||||
"message": "Custom usernames require upgrading to a Pro plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 220]]
|
||||
},
|
||||
"j9IZZ0": {
|
||||
"message": "Custom workspace URL",
|
||||
"placeholders": {},
|
||||
@@ -1985,7 +2083,10 @@
|
||||
"message": "Delete card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 76]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMenu.tsx", 74],
|
||||
["src/views/card/components/Dropdown.tsx", 76]
|
||||
],
|
||||
"translation": "Kaart verwijderen"
|
||||
},
|
||||
"njJFtc": {
|
||||
@@ -2171,6 +2272,9 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 36],
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 48],
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 68],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 17],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 23],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 29],
|
||||
@@ -2226,6 +2330,34 @@
|
||||
"origin": [["src/views/board/components/Filters.tsx", 122]],
|
||||
"translation": "Verloopt morgen"
|
||||
},
|
||||
"euc6Ns": {
|
||||
"message": "Duplicate",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Dupliceren"
|
||||
},
|
||||
"BTDPLo": {
|
||||
"message": "Duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 111],
|
||||
["src/views/board/components/CardContextMenu.tsx", 68]
|
||||
],
|
||||
"translation": "Kaart dupliceren"
|
||||
},
|
||||
"06EQqT": {
|
||||
"message": "Duplicating…",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Dupliceren…"
|
||||
},
|
||||
"ePK91l": {
|
||||
"message": "Edit",
|
||||
"placeholders": {},
|
||||
@@ -2338,6 +2470,22 @@
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 100]],
|
||||
"translation": "E-mailzichtbaarheid"
|
||||
},
|
||||
"bFREhu": {
|
||||
"message": "End of list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 200]
|
||||
],
|
||||
"translation": "Einde van lijst"
|
||||
},
|
||||
"SUXBxp": {
|
||||
"translation": "Engineering",
|
||||
"message": "Engineering",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"0+ewPp": {
|
||||
"message": "Enhancement",
|
||||
"placeholders": {},
|
||||
@@ -2794,6 +2942,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 77],
|
||||
["src/views/onboarding/select-plan/index.tsx", 78],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 331],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
@@ -2894,7 +3044,7 @@
|
||||
"message": "Get started by creating a new list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 539]],
|
||||
"origin": [["src/views/board/index.tsx", 655]],
|
||||
"translation": "Ga aan de slag door een nieuwe lijst te maken"
|
||||
},
|
||||
"oW13KZ": {
|
||||
@@ -3004,6 +3154,13 @@
|
||||
"origin": [["src/components/SideNavigation.tsx", 119]],
|
||||
"translation": "Ga naar sjablonen"
|
||||
},
|
||||
"SUvm1Y": {
|
||||
"translation": "Geschikt voor individuen die net beginnen en alleen de basisbehoeften hebben.",
|
||||
"message": "Good for individuals starting out who just need the essentials.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 79]]
|
||||
},
|
||||
"cdyS7J": {
|
||||
"message": "Google SSO",
|
||||
"placeholders": {},
|
||||
@@ -3314,7 +3471,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 114],
|
||||
["src/views/card/components/MemberSelector.tsx", 115],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 367]
|
||||
],
|
||||
"translation": "Lid uitnodigen"
|
||||
@@ -3386,6 +3543,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 31],
|
||||
["src/views/board/components/Filters.tsx", 155],
|
||||
["src/views/board/components/NewCardForm.tsx", 421],
|
||||
["src/views/card/index.tsx", 133]
|
||||
@@ -3497,6 +3655,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 80],
|
||||
["src/views/board/index.tsx", 305],
|
||||
["src/views/card/components/Dropdown.tsx", 42],
|
||||
["src/views/public/board/CardModal.tsx", 36],
|
||||
["src/views/public/board/index.tsx", 77]
|
||||
@@ -3507,7 +3666,10 @@
|
||||
"message": "List",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 124]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 117],
|
||||
["src/views/card/index.tsx", 124]
|
||||
],
|
||||
"translation": "Lijst"
|
||||
},
|
||||
"zQX5Dj": {
|
||||
@@ -3596,6 +3758,16 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Sjabloon maken"
|
||||
},
|
||||
"hB02vO": {
|
||||
"message": "Manage members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 51],
|
||||
["src/views/board/components/CardContextMenu.tsx", 38]
|
||||
],
|
||||
"translation": "Leden beheren"
|
||||
},
|
||||
"IDvohQ": {
|
||||
"message": "marked a checklist item as incomplete",
|
||||
"placeholders": {},
|
||||
@@ -3612,6 +3784,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 258]],
|
||||
"translation": "heeft checklistitem <0>{0}</0> als onvolledig gemarkeerd"
|
||||
},
|
||||
"vo2a+a": {
|
||||
"translation": "Marketing",
|
||||
"message": "Marketing",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"agPptk": {
|
||||
"message": "Medium",
|
||||
"placeholders": {},
|
||||
@@ -3683,6 +3862,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 62],
|
||||
["src/views/pricing/components/Pricing.tsx", 14],
|
||||
["src/views/pricing/index.tsx", 20]
|
||||
],
|
||||
@@ -3695,6 +3875,20 @@
|
||||
"origin": [["src/views/members/components/InviteMemberForm.tsx", 159]],
|
||||
"translation": "maandelijkse facturering"
|
||||
},
|
||||
"51UCsN": {
|
||||
"message": "Move to another list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 44]],
|
||||
"translation": "Verplaats naar andere lijst"
|
||||
},
|
||||
"J4+OTA": {
|
||||
"message": "Move to list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 70]],
|
||||
"translation": "Verplaats naar lijst"
|
||||
},
|
||||
"BOqTi5": {
|
||||
"message": "moved the card from <0>{0}</0> to<1>{1}</1>",
|
||||
"placeholders": {
|
||||
@@ -3806,7 +4000,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewListForm.tsx", 113],
|
||||
["src/views/board/index.tsx", 503]
|
||||
["src/views/board/index.tsx", 619]
|
||||
],
|
||||
"translation": "Nieuwe lijst"
|
||||
},
|
||||
@@ -3932,14 +4126,14 @@
|
||||
"message": "No lists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 535]],
|
||||
"origin": [["src/views/board/index.tsx", 651]],
|
||||
"translation": "Geen lijsten"
|
||||
},
|
||||
"fvLNDy": {
|
||||
"message": "No lists have been created yet",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 540]],
|
||||
"origin": [["src/views/board/index.tsx", 656]],
|
||||
"translation": "Er zijn nog geen lijsten aangemaakt"
|
||||
},
|
||||
"i30J2U": {
|
||||
@@ -4020,7 +4214,7 @@
|
||||
"message": "Open command menu",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 31]],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 34]],
|
||||
"translation": "Commandomenu openen"
|
||||
},
|
||||
"cFQEU/": {
|
||||
@@ -4236,6 +4430,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 86]],
|
||||
"translation": "Persoonlijk project"
|
||||
},
|
||||
"Oi+J+N": {
|
||||
"translation": "Kies een abonnement om te beginnen. Alle betaalde abonnementen hebben een gratis proefperiode van 14 dagen.",
|
||||
"message": "Pick a plan to get started. All paid plans include a 14-day free trial.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 125]]
|
||||
},
|
||||
"Iqh0Uv": {
|
||||
"message": "Planned",
|
||||
"placeholders": {},
|
||||
@@ -4331,8 +4532,8 @@
|
||||
["src/views/board/components/NewTemplateForm.tsx", 77],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 73],
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 194],
|
||||
["src/views/board/index.tsx", 250],
|
||||
["src/views/board/index.tsx", 217],
|
||||
["src/views/board/index.tsx", 273],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
@@ -4360,6 +4561,8 @@
|
||||
["src/views/members/components/InviteMemberForm.tsx", 104],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 241],
|
||||
["src/views/members/index.tsx", 66],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 101],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 150],
|
||||
["src/views/settings/components/Avatar.tsx", 200],
|
||||
["src/views/settings/components/DeleteAccountConfirmation.tsx", 40],
|
||||
["src/views/settings/components/DeleteWorkspaceConfirmation.tsx", 46],
|
||||
@@ -4387,12 +4590,24 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 76],
|
||||
["src/views/board/components/CardContextMoveListModal.tsx", 42],
|
||||
["src/views/board/index.tsx", 314],
|
||||
["src/views/card/components/Dropdown.tsx", 51],
|
||||
["src/views/public/board/CardModal.tsx", 45],
|
||||
["src/views/public/board/index.tsx", 86]
|
||||
],
|
||||
"translation": "Probeer het opnieuw."
|
||||
},
|
||||
"nYNMZZ": {
|
||||
"message": "Position in list (0 = first, leave empty for end)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 193]
|
||||
],
|
||||
"translation": "Positie in lijst (0 = eerste, leeg laten voor het einde)"
|
||||
},
|
||||
"aHCEmh": {
|
||||
"message": "Pricing",
|
||||
"placeholders": {},
|
||||
@@ -4438,6 +4653,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 91],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 333],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 70]
|
||||
],
|
||||
@@ -4695,7 +4911,8 @@
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 36],
|
||||
["src/views/home/components/Header.tsx", 13],
|
||||
["src/views/home/components/Header.tsx", 28]
|
||||
["src/views/home/components/Header.tsx", 28],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 161]
|
||||
],
|
||||
"translation": "Roadmap"
|
||||
},
|
||||
@@ -4814,6 +5031,15 @@
|
||||
"origin": [["src/views/home/components/Testimonials.tsx", 239]],
|
||||
"translation": "Bekijk wat onze gebruikers over Kan zeggen"
|
||||
},
|
||||
"zYRVNp": {
|
||||
"message": "Select a list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 131]
|
||||
],
|
||||
"translation": "Selecteer een lijst"
|
||||
},
|
||||
"wgNoIs": {
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
@@ -4884,7 +5110,11 @@
|
||||
"message": "Set due date",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/DueDateSelector.tsx", 121]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 20],
|
||||
["src/views/board/components/CardContextMenu.tsx", 56],
|
||||
["src/views/card/components/DueDateSelector.tsx", 121]
|
||||
],
|
||||
"translation": "Vervaldatum instellen"
|
||||
},
|
||||
"Eit43O": {
|
||||
@@ -4894,6 +5124,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 142]],
|
||||
"translation": "heeft de vervaldatum ingesteld"
|
||||
},
|
||||
"JjEJSy": {
|
||||
"translation": "Stel je werkruimte in",
|
||||
"message": "Set up your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 179]]
|
||||
},
|
||||
"Tz0i8g": {
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
@@ -4974,6 +5211,16 @@
|
||||
"origin": [["src/views/invite/index.tsx", 154]],
|
||||
"translation": "Inloggen"
|
||||
},
|
||||
"fcWrnU": {
|
||||
"translation": "Uitloggen",
|
||||
"message": "Sign out",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 284],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 362]
|
||||
]
|
||||
},
|
||||
"mErq7F": {
|
||||
"message": "Sign Up",
|
||||
"placeholders": {},
|
||||
@@ -5059,6 +5306,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 22]],
|
||||
"translation": "Softwareontwikkeling"
|
||||
},
|
||||
"6sKjjx": {
|
||||
"translation": "Solo",
|
||||
"message": "Solo",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 76]]
|
||||
},
|
||||
"vnS6Rf": {
|
||||
"message": "SSO",
|
||||
"placeholders": {},
|
||||
@@ -5158,6 +5412,13 @@
|
||||
"origin": [["src/components/UserMenu.tsx", 144]],
|
||||
"translation": "Systeem"
|
||||
},
|
||||
"KM6m8p": {
|
||||
"translation": "Team",
|
||||
"message": "Team",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 83]]
|
||||
},
|
||||
"bff61F": {
|
||||
"message": "Team Plan",
|
||||
"placeholders": {},
|
||||
@@ -5184,8 +5445,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 449]
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/board/index.tsx", 565]
|
||||
],
|
||||
"translation": "Sjabloon"
|
||||
},
|
||||
@@ -5279,6 +5540,15 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Het board is gedearchiveerd."
|
||||
},
|
||||
"nKBUeF": {
|
||||
"message": "The card has been duplicated.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 69]
|
||||
],
|
||||
"translation": "De kaart is gedupliceerd."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5401,6 +5671,20 @@
|
||||
],
|
||||
"translation": "De rechten van dit lid zijn teruggezet naar de standaardinstellingen van hun rol."
|
||||
},
|
||||
"HQVm6e": {
|
||||
"translation": "Deze URL is al in gebruik",
|
||||
"message": "This URL has already been taken",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 73]]
|
||||
},
|
||||
"gKmoow": {
|
||||
"translation": "Deze URL is gereserveerd",
|
||||
"message": "This URL is reserved",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 75]]
|
||||
},
|
||||
"OAYToL": {
|
||||
"message": "This will remove all custom member permissions in this workspace. Members will inherit permissions only from their roles.",
|
||||
"placeholders": {},
|
||||
@@ -5461,6 +5745,15 @@
|
||||
"origin": [["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 127]],
|
||||
"translation": "Titel"
|
||||
},
|
||||
"wK4OTM": {
|
||||
"message": "Title (optional)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 180]
|
||||
],
|
||||
"translation": "Titel (optioneel)"
|
||||
},
|
||||
"Se/UIp": {
|
||||
"message": "To Do",
|
||||
"placeholders": {},
|
||||
@@ -5563,6 +5856,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 312],
|
||||
["src/views/card/components/Dropdown.tsx", 49],
|
||||
["src/views/public/board/CardModal.tsx", 43],
|
||||
["src/views/public/board/index.tsx", 84]
|
||||
@@ -5604,7 +5898,10 @@
|
||||
"message": "Unable to create workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 158]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 100]
|
||||
],
|
||||
"translation": "Kan workspace niet aanmaken"
|
||||
},
|
||||
"WHHLh9": {
|
||||
@@ -5644,6 +5941,22 @@
|
||||
"origin": [["src/views/card/components/DeleteCommentConfirmation.tsx", 45]],
|
||||
"translation": "Kan opmerking niet verwijderen"
|
||||
},
|
||||
"Oo4E6p": {
|
||||
"message": "Unable to duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 75]
|
||||
],
|
||||
"translation": "Kan kaart niet dupliceren"
|
||||
},
|
||||
"K7k9u3": {
|
||||
"message": "Unable to move card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 41]],
|
||||
"translation": "Kan kaart niet verplaatsen"
|
||||
},
|
||||
"8yFGGF": {
|
||||
"message": "Unable to remove member",
|
||||
"placeholders": {},
|
||||
@@ -5676,6 +5989,13 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 40]],
|
||||
"translation": "Kan feedback niet verzenden"
|
||||
},
|
||||
"Q60WUZ": {
|
||||
"translation": "Kan afrekenen niet starten",
|
||||
"message": "Unable to start checkout",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 149]]
|
||||
},
|
||||
"T7Mywq": {
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
@@ -5702,7 +6022,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 249],
|
||||
["src/views/board/index.tsx", 272],
|
||||
["src/views/card/index.tsx", 231]
|
||||
],
|
||||
"translation": "Kan kaart niet bijwerken"
|
||||
@@ -5747,7 +6067,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 193],
|
||||
["src/views/board/index.tsx", 216],
|
||||
["src/views/card/components/ListSelector.tsx", 54]
|
||||
],
|
||||
"translation": "Kan lijst niet bijwerken"
|
||||
@@ -5883,6 +6203,13 @@
|
||||
],
|
||||
"translation": "Onbeperkt leden"
|
||||
},
|
||||
"8AwlaR": {
|
||||
"translation": "Onbeperkt aantal leden en een aangepaste werkruimte-URL voor teams die klaar zijn om te groeien.",
|
||||
"message": "Unlimited members and a custom workspace username for teams ready to scale.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 94]]
|
||||
},
|
||||
"Ws+3X+": {
|
||||
"message": "Unlimited seats and advanced features for growing teams.",
|
||||
"placeholders": {},
|
||||
@@ -5972,7 +6299,10 @@
|
||||
"message": "Upgrade to Pro ($29/month)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 373]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 373],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 243]
|
||||
],
|
||||
"translation": "Upgrade naar Pro ($29/maand)"
|
||||
},
|
||||
"b3Thhd": {
|
||||
@@ -6256,7 +6586,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 47],
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
@@ -6284,7 +6614,10 @@
|
||||
"message": "Workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 82]],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 253],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 82]
|
||||
],
|
||||
"translation": "Workspace-beschrijving"
|
||||
},
|
||||
"Ax/hYa": {
|
||||
@@ -6331,6 +6664,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 263],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 188],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 63]
|
||||
],
|
||||
"translation": "Workspace-naam"
|
||||
@@ -6438,6 +6772,13 @@
|
||||
"origin": [["src/views/settings/AccountSettings.tsx", 91]],
|
||||
"translation": "Je staat op het punt je wachtwoord te wijzigen."
|
||||
},
|
||||
"3WXdoZ": {
|
||||
"translation": "Je kunt dit later altijd wijzigen in de instellingen.",
|
||||
"message": "You can always change these later in settings.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 182]]
|
||||
},
|
||||
"aelko+": {
|
||||
"message": "You can get a custom workspace URL, like <0>kan.bn/kan</0>, by going into your <1>workspace settings</1> and purchasing a pro workspace subscription. All subscriptions help fund the development of the project!",
|
||||
"placeholders": {},
|
||||
@@ -6467,8 +6808,8 @@
|
||||
["src/views/board/components/List.tsx", 117],
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 58],
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 487],
|
||||
["src/views/board/index.tsx", 545],
|
||||
["src/views/board/index.tsx", 603],
|
||||
["src/views/board/index.tsx", 661],
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
@@ -6533,6 +6874,13 @@
|
||||
],
|
||||
"translation": "Je account is verwijderd."
|
||||
},
|
||||
"c4nMcR": {
|
||||
"translation": "Jouw avatar",
|
||||
"message": "Your avatar",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 229]]
|
||||
},
|
||||
"evg7+A": {
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
@@ -6619,6 +6967,20 @@
|
||||
"origin": [["src/pages/unsubscribe/index.tsx", 33]],
|
||||
"translation": "Je afmeldlink mist een token. Open de nieuwste e-mail en probeer het opnieuw."
|
||||
},
|
||||
"GRAGsB": {
|
||||
"translation": "Jouw werkruimte",
|
||||
"message": "Your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 322]]
|
||||
},
|
||||
"j0o6ml": {
|
||||
"translation": "Jouw werkruimtebeschrijving",
|
||||
"message": "Your workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 325]]
|
||||
},
|
||||
"GnSSGm": {
|
||||
"message": "Your workspace description has been updated.",
|
||||
"placeholders": {},
|
||||
@@ -6655,6 +7017,16 @@
|
||||
],
|
||||
"translation": "Je werkruimte-slug is bijgewerkt."
|
||||
},
|
||||
"OTxjpR": {
|
||||
"translation": "jouw-werkruimte",
|
||||
"message": "your-workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 197],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 198]
|
||||
]
|
||||
},
|
||||
"4DOCMI": {
|
||||
"message": "YouTube URL",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -71,7 +71,7 @@
|
||||
"0": ["isTemplate ? \"Template\" : \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 440]],
|
||||
"origin": [["src/views/board/index.tsx", 556]],
|
||||
"translation": "{0} nie znaleziono"
|
||||
},
|
||||
"0xWkkH": {
|
||||
@@ -238,6 +238,13 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 110]],
|
||||
"translation": "Dzienniki aktywności"
|
||||
},
|
||||
"UGCIzB": {
|
||||
"message": "Add / edit label",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 50]],
|
||||
"translation": "Dodaj / edytuj etykietę"
|
||||
},
|
||||
"B3xxao": {
|
||||
"message": "Add a card",
|
||||
"placeholders": {},
|
||||
@@ -288,8 +295,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/LabelSelector.tsx", 113],
|
||||
["src/views/card/components/LabelSelector.tsx", 118]
|
||||
["src/views/card/components/LabelSelector.tsx", 114],
|
||||
["src/views/card/components/LabelSelector.tsx", 119]
|
||||
],
|
||||
"translation": "Dodaj etykietę"
|
||||
},
|
||||
@@ -298,7 +305,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 134],
|
||||
["src/views/card/components/MemberSelector.tsx", 135],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 257]
|
||||
],
|
||||
"translation": "Dodaj członka"
|
||||
@@ -549,6 +556,13 @@
|
||||
],
|
||||
"translation": "Wystąpił nieoczekiwany błąd. Spróbuj ponownie później."
|
||||
},
|
||||
"YkfDoz": {
|
||||
"translation": "Rocznie",
|
||||
"message": "Annual",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 63]]
|
||||
},
|
||||
"3bqt9U": {
|
||||
"message": "Anyone with this link can join your workspace",
|
||||
"placeholders": {},
|
||||
@@ -749,6 +763,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 59]],
|
||||
"translation": "Oczekiwanie na klienta"
|
||||
},
|
||||
"iH8pgl": {
|
||||
"translation": "Wstecz",
|
||||
"message": "Back",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 275]]
|
||||
},
|
||||
"KNKCTb": {
|
||||
"message": "Backlog",
|
||||
"placeholders": {},
|
||||
@@ -791,6 +812,13 @@
|
||||
"origin": [["src/views/pricing/components/PricingTiers.tsx", 53]],
|
||||
"translation": "Najlepsze dla małych i rozwijających się zespołów wymagających współpracy"
|
||||
},
|
||||
"zt/6cS": {
|
||||
"translation": "Najlepszy dla małych zespołów, które chcą współpracować i działać szybciej razem.",
|
||||
"message": "Best for small teams who want to collaborate and move faster together.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 86]]
|
||||
},
|
||||
"qaS+1/": {
|
||||
"message": "Best for teams that want to scale without limits",
|
||||
"placeholders": {},
|
||||
@@ -842,7 +870,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/card/index.tsx", 317],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
@@ -1235,12 +1263,14 @@
|
||||
"origin": [
|
||||
["src/components/DeleteLabelConfirmation.tsx", 49],
|
||||
["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 176],
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 267],
|
||||
["src/views/board/components/DeleteBoardConfirmation.tsx", 44],
|
||||
["src/views/card/components/Comment.tsx", 195],
|
||||
["src/views/card/components/DeleteCardConfirmation.tsx", 86],
|
||||
["src/views/card/components/DeleteChecklistConfirmation.tsx", 64],
|
||||
["src/views/card/components/DeleteCommentConfirmation.tsx", 77],
|
||||
["src/views/members/components/DeleteMemberConfirmation.tsx", 55],
|
||||
["src/views/onboarding/select-plan/index.tsx", 209],
|
||||
["src/views/settings/components/Avatar.tsx", 287],
|
||||
["src/views/settings/components/ChangePasswordConfirmation.tsx", 168],
|
||||
[
|
||||
@@ -1261,6 +1291,15 @@
|
||||
"origin": [["src/views/card/index.tsx", 317]],
|
||||
"translation": "Karta"
|
||||
},
|
||||
"sU2uWc": {
|
||||
"message": "Card duplicated",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 67]
|
||||
],
|
||||
"translation": "Karta zduplikowana"
|
||||
},
|
||||
"fEY2vP": {
|
||||
"message": "Card not found",
|
||||
"placeholders": {},
|
||||
@@ -1283,6 +1322,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 307],
|
||||
["src/views/card/components/Dropdown.tsx", 44],
|
||||
["src/views/public/board/CardModal.tsx", 38]
|
||||
],
|
||||
@@ -1360,6 +1400,13 @@
|
||||
],
|
||||
"translation": "Checklisty"
|
||||
},
|
||||
"zMquA7": {
|
||||
"translation": "Wybierz plan",
|
||||
"message": "Choose a plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 122]]
|
||||
},
|
||||
"VHS0aJ": {
|
||||
"message": "Clear all custom permissions?",
|
||||
"placeholders": {},
|
||||
@@ -1617,6 +1664,16 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 40]],
|
||||
"translation": "Tworzenie treści"
|
||||
},
|
||||
"xGVfLh": {
|
||||
"translation": "Kontynuuj",
|
||||
"message": "Continue",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 212],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 291]
|
||||
]
|
||||
},
|
||||
"J2Wbjt": {
|
||||
"message": "Continue with ",
|
||||
"placeholders": {},
|
||||
@@ -1661,6 +1718,40 @@
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 58]],
|
||||
"translation": "Kopiuj link do karty"
|
||||
},
|
||||
"0utuU6": {
|
||||
"message": "Copy checklists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 257]
|
||||
],
|
||||
"translation": "Kopiuj listy kontrolne"
|
||||
},
|
||||
"fDQ7hA": {
|
||||
"message": "Copy labels",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 221]
|
||||
],
|
||||
"translation": "Kopiuj etykiety"
|
||||
},
|
||||
"1bJKhj": {
|
||||
"message": "Copy link to card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 62]],
|
||||
"translation": "Kopiuj link do karty"
|
||||
},
|
||||
"uvH2xS": {
|
||||
"message": "Copy members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 239]
|
||||
],
|
||||
"translation": "Kopiuj członków"
|
||||
},
|
||||
"9PaIxv": {
|
||||
"message": "Core features",
|
||||
"placeholders": {},
|
||||
@@ -1757,7 +1848,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewCardForm.tsx", 417],
|
||||
["src/views/card/components/LabelSelector.tsx", 100]
|
||||
["src/views/card/components/LabelSelector.tsx", 101]
|
||||
],
|
||||
"translation": "Utwórz nową etykietę"
|
||||
},
|
||||
@@ -1766,8 +1857,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 76],
|
||||
["src/views/board/index.tsx", 554]
|
||||
["src/views/board/index.tsx", 91],
|
||||
["src/views/board/index.tsx", 670]
|
||||
],
|
||||
"translation": "Utwórz nową listę"
|
||||
},
|
||||
@@ -1791,7 +1882,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 388],
|
||||
["src/components/WorkspaceMenu.tsx", 153]
|
||||
["src/components/WorkspaceMenu.tsx", 160]
|
||||
],
|
||||
"translation": "Utwórz workspace"
|
||||
},
|
||||
@@ -1891,6 +1982,13 @@
|
||||
],
|
||||
"translation": "Niestandardowa nazwa użytkownika"
|
||||
},
|
||||
"ZDPJBc": {
|
||||
"translation": "Niestandardowe nazwy użytkownika wymagają uaktualnienia do planu Pro",
|
||||
"message": "Custom usernames require upgrading to a Pro plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 220]]
|
||||
},
|
||||
"j9IZZ0": {
|
||||
"message": "Custom workspace URL",
|
||||
"placeholders": {},
|
||||
@@ -1985,7 +2083,10 @@
|
||||
"message": "Delete card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 76]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMenu.tsx", 74],
|
||||
["src/views/card/components/Dropdown.tsx", 76]
|
||||
],
|
||||
"translation": "Usuń kartę"
|
||||
},
|
||||
"njJFtc": {
|
||||
@@ -2171,6 +2272,9 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 36],
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 48],
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 68],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 17],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 23],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 29],
|
||||
@@ -2226,6 +2330,34 @@
|
||||
"origin": [["src/views/board/components/Filters.tsx", 122]],
|
||||
"translation": "Termin jutro"
|
||||
},
|
||||
"euc6Ns": {
|
||||
"message": "Duplicate",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplikuj"
|
||||
},
|
||||
"BTDPLo": {
|
||||
"message": "Duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 111],
|
||||
["src/views/board/components/CardContextMenu.tsx", 68]
|
||||
],
|
||||
"translation": "Duplikuj kartę"
|
||||
},
|
||||
"06EQqT": {
|
||||
"message": "Duplicating…",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplikowanie…"
|
||||
},
|
||||
"ePK91l": {
|
||||
"message": "Edit",
|
||||
"placeholders": {},
|
||||
@@ -2338,6 +2470,22 @@
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 100]],
|
||||
"translation": "Widoczność e-maila"
|
||||
},
|
||||
"bFREhu": {
|
||||
"message": "End of list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 200]
|
||||
],
|
||||
"translation": "Koniec listy"
|
||||
},
|
||||
"SUXBxp": {
|
||||
"translation": "Inżynieria",
|
||||
"message": "Engineering",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"0+ewPp": {
|
||||
"message": "Enhancement",
|
||||
"placeholders": {},
|
||||
@@ -2794,6 +2942,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 77],
|
||||
["src/views/onboarding/select-plan/index.tsx", 78],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 331],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
@@ -2894,7 +3044,7 @@
|
||||
"message": "Get started by creating a new list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 539]],
|
||||
"origin": [["src/views/board/index.tsx", 655]],
|
||||
"translation": "Rozpocznij, tworząc nową listę"
|
||||
},
|
||||
"oW13KZ": {
|
||||
@@ -3004,6 +3154,13 @@
|
||||
"origin": [["src/components/SideNavigation.tsx", 119]],
|
||||
"translation": "Przejdź do szablonów"
|
||||
},
|
||||
"SUvm1Y": {
|
||||
"translation": "Dobry dla osób zaczynających, które potrzebują tylko podstaw.",
|
||||
"message": "Good for individuals starting out who just need the essentials.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 79]]
|
||||
},
|
||||
"cdyS7J": {
|
||||
"message": "Google SSO",
|
||||
"placeholders": {},
|
||||
@@ -3314,7 +3471,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 114],
|
||||
["src/views/card/components/MemberSelector.tsx", 115],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 367]
|
||||
],
|
||||
"translation": "Zaproś członka"
|
||||
@@ -3386,6 +3543,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 31],
|
||||
["src/views/board/components/Filters.tsx", 155],
|
||||
["src/views/board/components/NewCardForm.tsx", 421],
|
||||
["src/views/card/index.tsx", 133]
|
||||
@@ -3497,6 +3655,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 80],
|
||||
["src/views/board/index.tsx", 305],
|
||||
["src/views/card/components/Dropdown.tsx", 42],
|
||||
["src/views/public/board/CardModal.tsx", 36],
|
||||
["src/views/public/board/index.tsx", 77]
|
||||
@@ -3507,7 +3666,10 @@
|
||||
"message": "List",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 124]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 117],
|
||||
["src/views/card/index.tsx", 124]
|
||||
],
|
||||
"translation": "Lista"
|
||||
},
|
||||
"zQX5Dj": {
|
||||
@@ -3596,6 +3758,16 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Utwórz szablon"
|
||||
},
|
||||
"hB02vO": {
|
||||
"message": "Manage members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 51],
|
||||
["src/views/board/components/CardContextMenu.tsx", 38]
|
||||
],
|
||||
"translation": "Zarządzaj członkami"
|
||||
},
|
||||
"IDvohQ": {
|
||||
"message": "marked a checklist item as incomplete",
|
||||
"placeholders": {},
|
||||
@@ -3612,6 +3784,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 258]],
|
||||
"translation": "oznaczył(a) element listy kontrolnej <0>{0}</0> jako nieukończony"
|
||||
},
|
||||
"vo2a+a": {
|
||||
"translation": "Marketing",
|
||||
"message": "Marketing",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"agPptk": {
|
||||
"message": "Medium",
|
||||
"placeholders": {},
|
||||
@@ -3683,6 +3862,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 62],
|
||||
["src/views/pricing/components/Pricing.tsx", 14],
|
||||
["src/views/pricing/index.tsx", 20]
|
||||
],
|
||||
@@ -3695,6 +3875,20 @@
|
||||
"origin": [["src/views/members/components/InviteMemberForm.tsx", 159]],
|
||||
"translation": "rozliczenie miesięczne"
|
||||
},
|
||||
"51UCsN": {
|
||||
"message": "Move to another list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 44]],
|
||||
"translation": "Przenieś do innej listy"
|
||||
},
|
||||
"J4+OTA": {
|
||||
"message": "Move to list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 70]],
|
||||
"translation": "Przenieś do listy"
|
||||
},
|
||||
"BOqTi5": {
|
||||
"message": "moved the card from <0>{0}</0> to<1>{1}</1>",
|
||||
"placeholders": {
|
||||
@@ -3806,7 +4000,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewListForm.tsx", 113],
|
||||
["src/views/board/index.tsx", 503]
|
||||
["src/views/board/index.tsx", 619]
|
||||
],
|
||||
"translation": "Nowa lista"
|
||||
},
|
||||
@@ -3932,14 +4126,14 @@
|
||||
"message": "No lists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 535]],
|
||||
"origin": [["src/views/board/index.tsx", 651]],
|
||||
"translation": "Brak list"
|
||||
},
|
||||
"fvLNDy": {
|
||||
"message": "No lists have been created yet",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 540]],
|
||||
"origin": [["src/views/board/index.tsx", 656]],
|
||||
"translation": "Nie utworzono jeszcze żadnych list"
|
||||
},
|
||||
"i30J2U": {
|
||||
@@ -4020,7 +4214,7 @@
|
||||
"message": "Open command menu",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 31]],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 34]],
|
||||
"translation": "Otwórz menu poleceń"
|
||||
},
|
||||
"cFQEU/": {
|
||||
@@ -4236,6 +4430,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 86]],
|
||||
"translation": "Projekt osobisty"
|
||||
},
|
||||
"Oi+J+N": {
|
||||
"translation": "Wybierz plan, aby rozpocząć. Wszystkie płatne plany zawierają 14-dniowy bezpłatny okres próbny.",
|
||||
"message": "Pick a plan to get started. All paid plans include a 14-day free trial.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 125]]
|
||||
},
|
||||
"Iqh0Uv": {
|
||||
"message": "Planned",
|
||||
"placeholders": {},
|
||||
@@ -4331,8 +4532,8 @@
|
||||
["src/views/board/components/NewTemplateForm.tsx", 77],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 73],
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 194],
|
||||
["src/views/board/index.tsx", 250],
|
||||
["src/views/board/index.tsx", 217],
|
||||
["src/views/board/index.tsx", 273],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
@@ -4360,6 +4561,8 @@
|
||||
["src/views/members/components/InviteMemberForm.tsx", 104],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 241],
|
||||
["src/views/members/index.tsx", 66],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 101],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 150],
|
||||
["src/views/settings/components/Avatar.tsx", 200],
|
||||
["src/views/settings/components/DeleteAccountConfirmation.tsx", 40],
|
||||
["src/views/settings/components/DeleteWorkspaceConfirmation.tsx", 46],
|
||||
@@ -4387,12 +4590,24 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 76],
|
||||
["src/views/board/components/CardContextMoveListModal.tsx", 42],
|
||||
["src/views/board/index.tsx", 314],
|
||||
["src/views/card/components/Dropdown.tsx", 51],
|
||||
["src/views/public/board/CardModal.tsx", 45],
|
||||
["src/views/public/board/index.tsx", 86]
|
||||
],
|
||||
"translation": "Spróbuj ponownie."
|
||||
},
|
||||
"nYNMZZ": {
|
||||
"message": "Position in list (0 = first, leave empty for end)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 193]
|
||||
],
|
||||
"translation": "Pozycja na liście (0 = pierwsza, puste pole = koniec)"
|
||||
},
|
||||
"aHCEmh": {
|
||||
"message": "Pricing",
|
||||
"placeholders": {},
|
||||
@@ -4438,6 +4653,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 91],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 333],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 70]
|
||||
],
|
||||
@@ -4695,7 +4911,8 @@
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 36],
|
||||
["src/views/home/components/Header.tsx", 13],
|
||||
["src/views/home/components/Header.tsx", 28]
|
||||
["src/views/home/components/Header.tsx", 28],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 161]
|
||||
],
|
||||
"translation": "Mapa drogowa"
|
||||
},
|
||||
@@ -4814,6 +5031,15 @@
|
||||
"origin": [["src/views/home/components/Testimonials.tsx", 239]],
|
||||
"translation": "Zobacz, co nasi użytkownicy mówią o Kan"
|
||||
},
|
||||
"zYRVNp": {
|
||||
"message": "Select a list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 131]
|
||||
],
|
||||
"translation": "Wybierz listę"
|
||||
},
|
||||
"wgNoIs": {
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
@@ -4884,7 +5110,11 @@
|
||||
"message": "Set due date",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/DueDateSelector.tsx", 121]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 20],
|
||||
["src/views/board/components/CardContextMenu.tsx", 56],
|
||||
["src/views/card/components/DueDateSelector.tsx", 121]
|
||||
],
|
||||
"translation": "Ustaw termin"
|
||||
},
|
||||
"Eit43O": {
|
||||
@@ -4894,6 +5124,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 142]],
|
||||
"translation": "ustaw termin"
|
||||
},
|
||||
"JjEJSy": {
|
||||
"translation": "Skonfiguruj swoją przestrzeń roboczą",
|
||||
"message": "Set up your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 179]]
|
||||
},
|
||||
"Tz0i8g": {
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
@@ -4974,6 +5211,16 @@
|
||||
"origin": [["src/views/invite/index.tsx", 154]],
|
||||
"translation": "Zaloguj się"
|
||||
},
|
||||
"fcWrnU": {
|
||||
"translation": "Wyloguj się",
|
||||
"message": "Sign out",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 284],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 362]
|
||||
]
|
||||
},
|
||||
"mErq7F": {
|
||||
"message": "Sign Up",
|
||||
"placeholders": {},
|
||||
@@ -5059,6 +5306,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 22]],
|
||||
"translation": "Software Development"
|
||||
},
|
||||
"6sKjjx": {
|
||||
"translation": "Solo",
|
||||
"message": "Solo",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 76]]
|
||||
},
|
||||
"vnS6Rf": {
|
||||
"message": "SSO",
|
||||
"placeholders": {},
|
||||
@@ -5158,6 +5412,13 @@
|
||||
"origin": [["src/components/UserMenu.tsx", 144]],
|
||||
"translation": "System"
|
||||
},
|
||||
"KM6m8p": {
|
||||
"translation": "Zespół",
|
||||
"message": "Team",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 83]]
|
||||
},
|
||||
"bff61F": {
|
||||
"message": "Team Plan",
|
||||
"placeholders": {},
|
||||
@@ -5184,8 +5445,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 449]
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/board/index.tsx", 565]
|
||||
],
|
||||
"translation": "Szablon"
|
||||
},
|
||||
@@ -5279,6 +5540,15 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Tablica została przywrócona z archiwum."
|
||||
},
|
||||
"nKBUeF": {
|
||||
"message": "The card has been duplicated.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 69]
|
||||
],
|
||||
"translation": "Karta została zduplikowana."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5401,6 +5671,20 @@
|
||||
],
|
||||
"translation": "Uprawnienia tego członka zostały zresetowane do domyślnych dla jego roli."
|
||||
},
|
||||
"HQVm6e": {
|
||||
"translation": "Ten adres URL jest już zajęty",
|
||||
"message": "This URL has already been taken",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 73]]
|
||||
},
|
||||
"gKmoow": {
|
||||
"translation": "Ten adres URL jest zarezerwowany",
|
||||
"message": "This URL is reserved",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 75]]
|
||||
},
|
||||
"OAYToL": {
|
||||
"message": "This will remove all custom member permissions in this workspace. Members will inherit permissions only from their roles.",
|
||||
"placeholders": {},
|
||||
@@ -5461,6 +5745,15 @@
|
||||
"origin": [["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 127]],
|
||||
"translation": "Tytuł"
|
||||
},
|
||||
"wK4OTM": {
|
||||
"message": "Title (optional)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 180]
|
||||
],
|
||||
"translation": "Tytuł (opcjonalnie)"
|
||||
},
|
||||
"Se/UIp": {
|
||||
"message": "To Do",
|
||||
"placeholders": {},
|
||||
@@ -5563,6 +5856,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 312],
|
||||
["src/views/card/components/Dropdown.tsx", 49],
|
||||
["src/views/public/board/CardModal.tsx", 43],
|
||||
["src/views/public/board/index.tsx", 84]
|
||||
@@ -5604,7 +5898,10 @@
|
||||
"message": "Unable to create workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 158]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 100]
|
||||
],
|
||||
"translation": "Nie można utworzyć workspace"
|
||||
},
|
||||
"WHHLh9": {
|
||||
@@ -5644,6 +5941,22 @@
|
||||
"origin": [["src/views/card/components/DeleteCommentConfirmation.tsx", 45]],
|
||||
"translation": "Nie można usunąć komentarza"
|
||||
},
|
||||
"Oo4E6p": {
|
||||
"message": "Unable to duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 75]
|
||||
],
|
||||
"translation": "Nie można zduplikować karty"
|
||||
},
|
||||
"K7k9u3": {
|
||||
"message": "Unable to move card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 41]],
|
||||
"translation": "Nie można przenieść karty"
|
||||
},
|
||||
"8yFGGF": {
|
||||
"message": "Unable to remove member",
|
||||
"placeholders": {},
|
||||
@@ -5676,6 +5989,13 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 40]],
|
||||
"translation": "Nie można wysłać opinii"
|
||||
},
|
||||
"Q60WUZ": {
|
||||
"translation": "Nie można rozpocząć procesu płatności",
|
||||
"message": "Unable to start checkout",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 149]]
|
||||
},
|
||||
"T7Mywq": {
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
@@ -5702,7 +6022,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 249],
|
||||
["src/views/board/index.tsx", 272],
|
||||
["src/views/card/index.tsx", 231]
|
||||
],
|
||||
"translation": "Nie można zaktualizować karty"
|
||||
@@ -5747,7 +6067,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 193],
|
||||
["src/views/board/index.tsx", 216],
|
||||
["src/views/card/components/ListSelector.tsx", 54]
|
||||
],
|
||||
"translation": "Nie można zaktualizować listy"
|
||||
@@ -5883,6 +6203,13 @@
|
||||
],
|
||||
"translation": "Nielimitowani członkowie"
|
||||
},
|
||||
"8AwlaR": {
|
||||
"translation": "Nieograniczona liczba członków i niestandardowa nazwa użytkownika przestrzeni roboczej dla zespołów gotowych do rozwoju.",
|
||||
"message": "Unlimited members and a custom workspace username for teams ready to scale.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 94]]
|
||||
},
|
||||
"Ws+3X+": {
|
||||
"message": "Unlimited seats and advanced features for growing teams.",
|
||||
"placeholders": {},
|
||||
@@ -5972,7 +6299,10 @@
|
||||
"message": "Upgrade to Pro ($29/month)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 373]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 373],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 243]
|
||||
],
|
||||
"translation": "Ulepsz do Pro (29 $/miesiąc)"
|
||||
},
|
||||
"b3Thhd": {
|
||||
@@ -6256,7 +6586,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 47],
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
@@ -6284,7 +6614,10 @@
|
||||
"message": "Workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 82]],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 253],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 82]
|
||||
],
|
||||
"translation": "Opis przestrzeni roboczej"
|
||||
},
|
||||
"Ax/hYa": {
|
||||
@@ -6331,6 +6664,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 263],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 188],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 63]
|
||||
],
|
||||
"translation": "Nazwa przestrzeni roboczej"
|
||||
@@ -6438,6 +6772,13 @@
|
||||
"origin": [["src/views/settings/AccountSettings.tsx", 91]],
|
||||
"translation": "Zaraz zmienisz swoje hasło."
|
||||
},
|
||||
"3WXdoZ": {
|
||||
"translation": "Zawsze możesz to później zmienić w ustawieniach.",
|
||||
"message": "You can always change these later in settings.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 182]]
|
||||
},
|
||||
"aelko+": {
|
||||
"message": "You can get a custom workspace URL, like <0>kan.bn/kan</0>, by going into your <1>workspace settings</1> and purchasing a pro workspace subscription. All subscriptions help fund the development of the project!",
|
||||
"placeholders": {},
|
||||
@@ -6467,8 +6808,8 @@
|
||||
["src/views/board/components/List.tsx", 117],
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 58],
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 487],
|
||||
["src/views/board/index.tsx", 545],
|
||||
["src/views/board/index.tsx", 603],
|
||||
["src/views/board/index.tsx", 661],
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
@@ -6533,6 +6874,13 @@
|
||||
],
|
||||
"translation": "Twoje konto zostało usunięte."
|
||||
},
|
||||
"c4nMcR": {
|
||||
"translation": "Twój awatar",
|
||||
"message": "Your avatar",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 229]]
|
||||
},
|
||||
"evg7+A": {
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
@@ -6619,6 +6967,20 @@
|
||||
"origin": [["src/pages/unsubscribe/index.tsx", 33]],
|
||||
"translation": "Twój link do wypisania się nie zawiera tokena. Otwórz najnowszy e-mail i spróbuj ponownie."
|
||||
},
|
||||
"GRAGsB": {
|
||||
"translation": "Twoja przestrzeń robocza",
|
||||
"message": "Your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 322]]
|
||||
},
|
||||
"j0o6ml": {
|
||||
"translation": "Opis Twojej przestrzeni roboczej",
|
||||
"message": "Your workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 325]]
|
||||
},
|
||||
"GnSSGm": {
|
||||
"message": "Your workspace description has been updated.",
|
||||
"placeholders": {},
|
||||
@@ -6655,6 +7017,16 @@
|
||||
],
|
||||
"translation": "Slug Twojego workspace został zaktualizowany."
|
||||
},
|
||||
"OTxjpR": {
|
||||
"translation": "twoja-przestrzen",
|
||||
"message": "your-workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 197],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 198]
|
||||
]
|
||||
},
|
||||
"4DOCMI": {
|
||||
"message": "YouTube URL",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -71,7 +71,7 @@
|
||||
"0": ["isTemplate ? \"Template\" : \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 440]],
|
||||
"origin": [["src/views/board/index.tsx", 556]],
|
||||
"translation": "{0} não encontrado"
|
||||
},
|
||||
"0xWkkH": {
|
||||
@@ -238,6 +238,13 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 110]],
|
||||
"translation": "Registros de atividades"
|
||||
},
|
||||
"UGCIzB": {
|
||||
"message": "Add / edit label",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 50]],
|
||||
"translation": "Adicionar / editar etiqueta"
|
||||
},
|
||||
"B3xxao": {
|
||||
"message": "Add a card",
|
||||
"placeholders": {},
|
||||
@@ -288,8 +295,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/LabelSelector.tsx", 113],
|
||||
["src/views/card/components/LabelSelector.tsx", 118]
|
||||
["src/views/card/components/LabelSelector.tsx", 114],
|
||||
["src/views/card/components/LabelSelector.tsx", 119]
|
||||
],
|
||||
"translation": "Adicionar etiqueta"
|
||||
},
|
||||
@@ -298,7 +305,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 134],
|
||||
["src/views/card/components/MemberSelector.tsx", 135],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 257]
|
||||
],
|
||||
"translation": "Adicionar membro"
|
||||
@@ -549,6 +556,13 @@
|
||||
],
|
||||
"translation": "Ocorreu um erro inesperado. Por favor, tente novamente mais tarde."
|
||||
},
|
||||
"YkfDoz": {
|
||||
"translation": "Anual",
|
||||
"message": "Annual",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 63]]
|
||||
},
|
||||
"3bqt9U": {
|
||||
"message": "Anyone with this link can join your workspace",
|
||||
"placeholders": {},
|
||||
@@ -749,6 +763,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 59]],
|
||||
"translation": "Aguardando cliente"
|
||||
},
|
||||
"iH8pgl": {
|
||||
"translation": "Voltar",
|
||||
"message": "Back",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 275]]
|
||||
},
|
||||
"KNKCTb": {
|
||||
"message": "Backlog",
|
||||
"placeholders": {},
|
||||
@@ -791,6 +812,13 @@
|
||||
"origin": [["src/views/pricing/components/PricingTiers.tsx", 53]],
|
||||
"translation": "Ideal para equipes pequenas e em crescimento que precisam de colaboração"
|
||||
},
|
||||
"zt/6cS": {
|
||||
"translation": "Ideal para pequenas equipes que desejam colaborar e avançar mais rápido juntas.",
|
||||
"message": "Best for small teams who want to collaborate and move faster together.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 86]]
|
||||
},
|
||||
"qaS+1/": {
|
||||
"message": "Best for teams that want to scale without limits",
|
||||
"placeholders": {},
|
||||
@@ -842,7 +870,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/card/index.tsx", 317],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
@@ -1235,12 +1263,14 @@
|
||||
"origin": [
|
||||
["src/components/DeleteLabelConfirmation.tsx", 49],
|
||||
["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 176],
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 267],
|
||||
["src/views/board/components/DeleteBoardConfirmation.tsx", 44],
|
||||
["src/views/card/components/Comment.tsx", 195],
|
||||
["src/views/card/components/DeleteCardConfirmation.tsx", 86],
|
||||
["src/views/card/components/DeleteChecklistConfirmation.tsx", 64],
|
||||
["src/views/card/components/DeleteCommentConfirmation.tsx", 77],
|
||||
["src/views/members/components/DeleteMemberConfirmation.tsx", 55],
|
||||
["src/views/onboarding/select-plan/index.tsx", 209],
|
||||
["src/views/settings/components/Avatar.tsx", 287],
|
||||
["src/views/settings/components/ChangePasswordConfirmation.tsx", 168],
|
||||
[
|
||||
@@ -1261,6 +1291,15 @@
|
||||
"origin": [["src/views/card/index.tsx", 317]],
|
||||
"translation": "Cartão"
|
||||
},
|
||||
"sU2uWc": {
|
||||
"message": "Card duplicated",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 67]
|
||||
],
|
||||
"translation": "Cartão duplicado"
|
||||
},
|
||||
"fEY2vP": {
|
||||
"message": "Card not found",
|
||||
"placeholders": {},
|
||||
@@ -1283,6 +1322,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 307],
|
||||
["src/views/card/components/Dropdown.tsx", 44],
|
||||
["src/views/public/board/CardModal.tsx", 38]
|
||||
],
|
||||
@@ -1360,6 +1400,13 @@
|
||||
],
|
||||
"translation": "Checklists"
|
||||
},
|
||||
"zMquA7": {
|
||||
"translation": "Escolha um plano",
|
||||
"message": "Choose a plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 122]]
|
||||
},
|
||||
"VHS0aJ": {
|
||||
"message": "Clear all custom permissions?",
|
||||
"placeholders": {},
|
||||
@@ -1617,6 +1664,16 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 40]],
|
||||
"translation": "Criação de conteúdo"
|
||||
},
|
||||
"xGVfLh": {
|
||||
"translation": "Continuar",
|
||||
"message": "Continue",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 212],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 291]
|
||||
]
|
||||
},
|
||||
"J2Wbjt": {
|
||||
"message": "Continue with ",
|
||||
"placeholders": {},
|
||||
@@ -1661,6 +1718,40 @@
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 58]],
|
||||
"translation": "Copiar link do cartão"
|
||||
},
|
||||
"0utuU6": {
|
||||
"message": "Copy checklists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 257]
|
||||
],
|
||||
"translation": "Copiar checklists"
|
||||
},
|
||||
"fDQ7hA": {
|
||||
"message": "Copy labels",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 221]
|
||||
],
|
||||
"translation": "Copiar etiquetas"
|
||||
},
|
||||
"1bJKhj": {
|
||||
"message": "Copy link to card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 62]],
|
||||
"translation": "Copiar link do cartão"
|
||||
},
|
||||
"uvH2xS": {
|
||||
"message": "Copy members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 239]
|
||||
],
|
||||
"translation": "Copiar membros"
|
||||
},
|
||||
"9PaIxv": {
|
||||
"message": "Core features",
|
||||
"placeholders": {},
|
||||
@@ -1757,7 +1848,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewCardForm.tsx", 417],
|
||||
["src/views/card/components/LabelSelector.tsx", 100]
|
||||
["src/views/card/components/LabelSelector.tsx", 101]
|
||||
],
|
||||
"translation": "Criar nova etiqueta"
|
||||
},
|
||||
@@ -1766,8 +1857,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 76],
|
||||
["src/views/board/index.tsx", 554]
|
||||
["src/views/board/index.tsx", 91],
|
||||
["src/views/board/index.tsx", 670]
|
||||
],
|
||||
"translation": "Criar nova lista"
|
||||
},
|
||||
@@ -1791,7 +1882,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 388],
|
||||
["src/components/WorkspaceMenu.tsx", 153]
|
||||
["src/components/WorkspaceMenu.tsx", 160]
|
||||
],
|
||||
"translation": "Criar workspace"
|
||||
},
|
||||
@@ -1891,6 +1982,13 @@
|
||||
],
|
||||
"translation": "Nome de usuário personalizado"
|
||||
},
|
||||
"ZDPJBc": {
|
||||
"translation": "Nomes de usuário personalizados exigem atualização para um plano Pro",
|
||||
"message": "Custom usernames require upgrading to a Pro plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 220]]
|
||||
},
|
||||
"j9IZZ0": {
|
||||
"message": "Custom workspace URL",
|
||||
"placeholders": {},
|
||||
@@ -1985,7 +2083,10 @@
|
||||
"message": "Delete card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 76]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMenu.tsx", 74],
|
||||
["src/views/card/components/Dropdown.tsx", 76]
|
||||
],
|
||||
"translation": "Excluir cartão"
|
||||
},
|
||||
"njJFtc": {
|
||||
@@ -2171,6 +2272,9 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 36],
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 48],
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 68],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 17],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 23],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 29],
|
||||
@@ -2226,6 +2330,34 @@
|
||||
"origin": [["src/views/board/components/Filters.tsx", 122]],
|
||||
"translation": "Vence amanhã"
|
||||
},
|
||||
"euc6Ns": {
|
||||
"message": "Duplicate",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplicar"
|
||||
},
|
||||
"BTDPLo": {
|
||||
"message": "Duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 111],
|
||||
["src/views/board/components/CardContextMenu.tsx", 68]
|
||||
],
|
||||
"translation": "Duplicar cartão"
|
||||
},
|
||||
"06EQqT": {
|
||||
"message": "Duplicating…",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Duplicando…"
|
||||
},
|
||||
"ePK91l": {
|
||||
"message": "Edit",
|
||||
"placeholders": {},
|
||||
@@ -2338,6 +2470,22 @@
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 100]],
|
||||
"translation": "Visibilidade do email"
|
||||
},
|
||||
"bFREhu": {
|
||||
"message": "End of list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 200]
|
||||
],
|
||||
"translation": "Fim da lista"
|
||||
},
|
||||
"SUXBxp": {
|
||||
"translation": "Engenharia",
|
||||
"message": "Engineering",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"0+ewPp": {
|
||||
"message": "Enhancement",
|
||||
"placeholders": {},
|
||||
@@ -2794,6 +2942,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 77],
|
||||
["src/views/onboarding/select-plan/index.tsx", 78],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 331],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
@@ -2894,7 +3044,7 @@
|
||||
"message": "Get started by creating a new list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 539]],
|
||||
"origin": [["src/views/board/index.tsx", 655]],
|
||||
"translation": "Comece criando uma nova lista"
|
||||
},
|
||||
"oW13KZ": {
|
||||
@@ -3004,6 +3154,13 @@
|
||||
"origin": [["src/components/SideNavigation.tsx", 119]],
|
||||
"translation": "Ir para modelos"
|
||||
},
|
||||
"SUvm1Y": {
|
||||
"translation": "Bom para indivíduos começando que precisam apenas do essencial.",
|
||||
"message": "Good for individuals starting out who just need the essentials.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 79]]
|
||||
},
|
||||
"cdyS7J": {
|
||||
"message": "Google SSO",
|
||||
"placeholders": {},
|
||||
@@ -3314,7 +3471,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 114],
|
||||
["src/views/card/components/MemberSelector.tsx", 115],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 367]
|
||||
],
|
||||
"translation": "Convidar membro"
|
||||
@@ -3386,6 +3543,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 31],
|
||||
["src/views/board/components/Filters.tsx", 155],
|
||||
["src/views/board/components/NewCardForm.tsx", 421],
|
||||
["src/views/card/index.tsx", 133]
|
||||
@@ -3497,6 +3655,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 80],
|
||||
["src/views/board/index.tsx", 305],
|
||||
["src/views/card/components/Dropdown.tsx", 42],
|
||||
["src/views/public/board/CardModal.tsx", 36],
|
||||
["src/views/public/board/index.tsx", 77]
|
||||
@@ -3507,7 +3666,10 @@
|
||||
"message": "List",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 124]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 117],
|
||||
["src/views/card/index.tsx", 124]
|
||||
],
|
||||
"translation": "Lista"
|
||||
},
|
||||
"zQX5Dj": {
|
||||
@@ -3596,6 +3758,16 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Criar modelo"
|
||||
},
|
||||
"hB02vO": {
|
||||
"message": "Manage members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 51],
|
||||
["src/views/board/components/CardContextMenu.tsx", 38]
|
||||
],
|
||||
"translation": "Gerenciar membros"
|
||||
},
|
||||
"IDvohQ": {
|
||||
"message": "marked a checklist item as incomplete",
|
||||
"placeholders": {},
|
||||
@@ -3612,6 +3784,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 258]],
|
||||
"translation": "marcou o item da checklist <0>{0}</0> como incompleto"
|
||||
},
|
||||
"vo2a+a": {
|
||||
"translation": "Marketing",
|
||||
"message": "Marketing",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"agPptk": {
|
||||
"message": "Medium",
|
||||
"placeholders": {},
|
||||
@@ -3683,6 +3862,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 62],
|
||||
["src/views/pricing/components/Pricing.tsx", 14],
|
||||
["src/views/pricing/index.tsx", 20]
|
||||
],
|
||||
@@ -3695,6 +3875,20 @@
|
||||
"origin": [["src/views/members/components/InviteMemberForm.tsx", 159]],
|
||||
"translation": "cobrança mensal"
|
||||
},
|
||||
"51UCsN": {
|
||||
"message": "Move to another list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 44]],
|
||||
"translation": "Mover para outra lista"
|
||||
},
|
||||
"J4+OTA": {
|
||||
"message": "Move to list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 70]],
|
||||
"translation": "Mover para lista"
|
||||
},
|
||||
"BOqTi5": {
|
||||
"message": "moved the card from <0>{0}</0> to<1>{1}</1>",
|
||||
"placeholders": {
|
||||
@@ -3806,7 +4000,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewListForm.tsx", 113],
|
||||
["src/views/board/index.tsx", 503]
|
||||
["src/views/board/index.tsx", 619]
|
||||
],
|
||||
"translation": "Nova lista"
|
||||
},
|
||||
@@ -3932,14 +4126,14 @@
|
||||
"message": "No lists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 535]],
|
||||
"origin": [["src/views/board/index.tsx", 651]],
|
||||
"translation": "Nenhuma lista"
|
||||
},
|
||||
"fvLNDy": {
|
||||
"message": "No lists have been created yet",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 540]],
|
||||
"origin": [["src/views/board/index.tsx", 656]],
|
||||
"translation": "Nenhuma lista foi criada ainda"
|
||||
},
|
||||
"i30J2U": {
|
||||
@@ -4020,7 +4214,7 @@
|
||||
"message": "Open command menu",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 31]],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 34]],
|
||||
"translation": "Abrir menu de comandos"
|
||||
},
|
||||
"cFQEU/": {
|
||||
@@ -4236,6 +4430,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 86]],
|
||||
"translation": "Projeto pessoal"
|
||||
},
|
||||
"Oi+J+N": {
|
||||
"translation": "Escolha um plano para começar. Todos os planos pagos incluem 14 dias de teste grátis.",
|
||||
"message": "Pick a plan to get started. All paid plans include a 14-day free trial.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 125]]
|
||||
},
|
||||
"Iqh0Uv": {
|
||||
"message": "Planned",
|
||||
"placeholders": {},
|
||||
@@ -4331,8 +4532,8 @@
|
||||
["src/views/board/components/NewTemplateForm.tsx", 77],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 73],
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 194],
|
||||
["src/views/board/index.tsx", 250],
|
||||
["src/views/board/index.tsx", 217],
|
||||
["src/views/board/index.tsx", 273],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
@@ -4360,6 +4561,8 @@
|
||||
["src/views/members/components/InviteMemberForm.tsx", 104],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 241],
|
||||
["src/views/members/index.tsx", 66],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 101],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 150],
|
||||
["src/views/settings/components/Avatar.tsx", 200],
|
||||
["src/views/settings/components/DeleteAccountConfirmation.tsx", 40],
|
||||
["src/views/settings/components/DeleteWorkspaceConfirmation.tsx", 46],
|
||||
@@ -4387,12 +4590,24 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 76],
|
||||
["src/views/board/components/CardContextMoveListModal.tsx", 42],
|
||||
["src/views/board/index.tsx", 314],
|
||||
["src/views/card/components/Dropdown.tsx", 51],
|
||||
["src/views/public/board/CardModal.tsx", 45],
|
||||
["src/views/public/board/index.tsx", 86]
|
||||
],
|
||||
"translation": "Por favor, tente novamente."
|
||||
},
|
||||
"nYNMZZ": {
|
||||
"message": "Position in list (0 = first, leave empty for end)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 193]
|
||||
],
|
||||
"translation": "Posição na lista (0 = primeira, deixe vazio para o final)"
|
||||
},
|
||||
"aHCEmh": {
|
||||
"message": "Pricing",
|
||||
"placeholders": {},
|
||||
@@ -4438,6 +4653,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 91],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 333],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 70]
|
||||
],
|
||||
@@ -4695,7 +4911,8 @@
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 36],
|
||||
["src/views/home/components/Header.tsx", 13],
|
||||
["src/views/home/components/Header.tsx", 28]
|
||||
["src/views/home/components/Header.tsx", 28],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 161]
|
||||
],
|
||||
"translation": "Roadmap"
|
||||
},
|
||||
@@ -4814,6 +5031,15 @@
|
||||
"origin": [["src/views/home/components/Testimonials.tsx", 239]],
|
||||
"translation": "Veja o que nossos usuários estão dizendo sobre o Kan"
|
||||
},
|
||||
"zYRVNp": {
|
||||
"message": "Select a list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 131]
|
||||
],
|
||||
"translation": "Selecione uma lista"
|
||||
},
|
||||
"wgNoIs": {
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
@@ -4884,7 +5110,11 @@
|
||||
"message": "Set due date",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/DueDateSelector.tsx", 121]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 20],
|
||||
["src/views/board/components/CardContextMenu.tsx", 56],
|
||||
["src/views/card/components/DueDateSelector.tsx", 121]
|
||||
],
|
||||
"translation": "Definir data de vencimento"
|
||||
},
|
||||
"Eit43O": {
|
||||
@@ -4894,6 +5124,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 142]],
|
||||
"translation": "definiu a data de vencimento"
|
||||
},
|
||||
"JjEJSy": {
|
||||
"translation": "Configure seu workspace",
|
||||
"message": "Set up your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 179]]
|
||||
},
|
||||
"Tz0i8g": {
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
@@ -4974,6 +5211,16 @@
|
||||
"origin": [["src/views/invite/index.tsx", 154]],
|
||||
"translation": "Entrar"
|
||||
},
|
||||
"fcWrnU": {
|
||||
"translation": "Sair",
|
||||
"message": "Sign out",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 284],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 362]
|
||||
]
|
||||
},
|
||||
"mErq7F": {
|
||||
"message": "Sign Up",
|
||||
"placeholders": {},
|
||||
@@ -5059,6 +5306,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 22]],
|
||||
"translation": "Desenvolvimento de software"
|
||||
},
|
||||
"6sKjjx": {
|
||||
"translation": "Solo",
|
||||
"message": "Solo",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 76]]
|
||||
},
|
||||
"vnS6Rf": {
|
||||
"message": "SSO",
|
||||
"placeholders": {},
|
||||
@@ -5158,6 +5412,13 @@
|
||||
"origin": [["src/components/UserMenu.tsx", 144]],
|
||||
"translation": "Sistema"
|
||||
},
|
||||
"KM6m8p": {
|
||||
"translation": "Equipe",
|
||||
"message": "Team",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 83]]
|
||||
},
|
||||
"bff61F": {
|
||||
"message": "Team Plan",
|
||||
"placeholders": {},
|
||||
@@ -5184,8 +5445,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 449]
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/board/index.tsx", 565]
|
||||
],
|
||||
"translation": "Modelo"
|
||||
},
|
||||
@@ -5279,6 +5540,15 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "O quadro foi desarquivado."
|
||||
},
|
||||
"nKBUeF": {
|
||||
"message": "The card has been duplicated.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 69]
|
||||
],
|
||||
"translation": "O cartão foi duplicado."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5401,6 +5671,20 @@
|
||||
],
|
||||
"translation": "As permissões deste membro foram redefinidas para os padrões de sua função."
|
||||
},
|
||||
"HQVm6e": {
|
||||
"translation": "Esta URL já está em uso",
|
||||
"message": "This URL has already been taken",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 73]]
|
||||
},
|
||||
"gKmoow": {
|
||||
"translation": "Esta URL é reservada",
|
||||
"message": "This URL is reserved",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 75]]
|
||||
},
|
||||
"OAYToL": {
|
||||
"message": "This will remove all custom member permissions in this workspace. Members will inherit permissions only from their roles.",
|
||||
"placeholders": {},
|
||||
@@ -5461,6 +5745,15 @@
|
||||
"origin": [["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 127]],
|
||||
"translation": "Título"
|
||||
},
|
||||
"wK4OTM": {
|
||||
"message": "Title (optional)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 180]
|
||||
],
|
||||
"translation": "Título (opcional)"
|
||||
},
|
||||
"Se/UIp": {
|
||||
"message": "To Do",
|
||||
"placeholders": {},
|
||||
@@ -5563,6 +5856,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 312],
|
||||
["src/views/card/components/Dropdown.tsx", 49],
|
||||
["src/views/public/board/CardModal.tsx", 43],
|
||||
["src/views/public/board/index.tsx", 84]
|
||||
@@ -5604,7 +5898,10 @@
|
||||
"message": "Unable to create workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 158]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 100]
|
||||
],
|
||||
"translation": "Não foi possível criar workspace"
|
||||
},
|
||||
"WHHLh9": {
|
||||
@@ -5644,6 +5941,22 @@
|
||||
"origin": [["src/views/card/components/DeleteCommentConfirmation.tsx", 45]],
|
||||
"translation": "Não foi possível excluir o comentário"
|
||||
},
|
||||
"Oo4E6p": {
|
||||
"message": "Unable to duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 75]
|
||||
],
|
||||
"translation": "Não foi possível duplicar o cartão"
|
||||
},
|
||||
"K7k9u3": {
|
||||
"message": "Unable to move card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 41]],
|
||||
"translation": "Não foi possível mover o cartão"
|
||||
},
|
||||
"8yFGGF": {
|
||||
"message": "Unable to remove member",
|
||||
"placeholders": {},
|
||||
@@ -5676,6 +5989,13 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 40]],
|
||||
"translation": "Não foi possível enviar o feedback"
|
||||
},
|
||||
"Q60WUZ": {
|
||||
"translation": "Não foi possível iniciar o checkout",
|
||||
"message": "Unable to start checkout",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 149]]
|
||||
},
|
||||
"T7Mywq": {
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
@@ -5702,7 +6022,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 249],
|
||||
["src/views/board/index.tsx", 272],
|
||||
["src/views/card/index.tsx", 231]
|
||||
],
|
||||
"translation": "Não foi possível atualizar o cartão"
|
||||
@@ -5747,7 +6067,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 193],
|
||||
["src/views/board/index.tsx", 216],
|
||||
["src/views/card/components/ListSelector.tsx", 54]
|
||||
],
|
||||
"translation": "Não foi possível atualizar a lista"
|
||||
@@ -5883,6 +6203,13 @@
|
||||
],
|
||||
"translation": "Membros ilimitados"
|
||||
},
|
||||
"8AwlaR": {
|
||||
"translation": "Membros ilimitados e um nome de usuário personalizado para equipes prontas para crescer.",
|
||||
"message": "Unlimited members and a custom workspace username for teams ready to scale.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 94]]
|
||||
},
|
||||
"Ws+3X+": {
|
||||
"message": "Unlimited seats and advanced features for growing teams.",
|
||||
"placeholders": {},
|
||||
@@ -5972,7 +6299,10 @@
|
||||
"message": "Upgrade to Pro ($29/month)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 373]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 373],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 243]
|
||||
],
|
||||
"translation": "Fazer upgrade para Pro ($29/mês)"
|
||||
},
|
||||
"b3Thhd": {
|
||||
@@ -6256,7 +6586,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 47],
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
@@ -6284,7 +6614,10 @@
|
||||
"message": "Workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 82]],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 253],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 82]
|
||||
],
|
||||
"translation": "Descrição do workspace"
|
||||
},
|
||||
"Ax/hYa": {
|
||||
@@ -6331,6 +6664,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 263],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 188],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 63]
|
||||
],
|
||||
"translation": "Nome do workspace"
|
||||
@@ -6438,6 +6772,13 @@
|
||||
"origin": [["src/views/settings/AccountSettings.tsx", 91]],
|
||||
"translation": "Você está prestes a alterar sua senha."
|
||||
},
|
||||
"3WXdoZ": {
|
||||
"translation": "Você pode alterar isso depois nas configurações.",
|
||||
"message": "You can always change these later in settings.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 182]]
|
||||
},
|
||||
"aelko+": {
|
||||
"message": "You can get a custom workspace URL, like <0>kan.bn/kan</0>, by going into your <1>workspace settings</1> and purchasing a pro workspace subscription. All subscriptions help fund the development of the project!",
|
||||
"placeholders": {},
|
||||
@@ -6467,8 +6808,8 @@
|
||||
["src/views/board/components/List.tsx", 117],
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 58],
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 487],
|
||||
["src/views/board/index.tsx", 545],
|
||||
["src/views/board/index.tsx", 603],
|
||||
["src/views/board/index.tsx", 661],
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
@@ -6533,6 +6874,13 @@
|
||||
],
|
||||
"translation": "Sua conta foi excluída."
|
||||
},
|
||||
"c4nMcR": {
|
||||
"translation": "Seu avatar",
|
||||
"message": "Your avatar",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 229]]
|
||||
},
|
||||
"evg7+A": {
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
@@ -6619,6 +6967,20 @@
|
||||
"origin": [["src/pages/unsubscribe/index.tsx", 33]],
|
||||
"translation": "Seu link de cancelamento de inscrição está sem um token. Por favor, abra o e-mail mais recente e tente novamente."
|
||||
},
|
||||
"GRAGsB": {
|
||||
"translation": "Seu workspace",
|
||||
"message": "Your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 322]]
|
||||
},
|
||||
"j0o6ml": {
|
||||
"translation": "Descrição do seu workspace",
|
||||
"message": "Your workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 325]]
|
||||
},
|
||||
"GnSSGm": {
|
||||
"message": "Your workspace description has been updated.",
|
||||
"placeholders": {},
|
||||
@@ -6655,6 +7017,16 @@
|
||||
],
|
||||
"translation": "O slug do seu workspace foi atualizado."
|
||||
},
|
||||
"OTxjpR": {
|
||||
"translation": "seu-workspace",
|
||||
"message": "your-workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 197],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 198]
|
||||
]
|
||||
},
|
||||
"4DOCMI": {
|
||||
"message": "YouTube URL",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -71,7 +71,7 @@
|
||||
"0": ["isTemplate ? \"Template\" : \"Board\""]
|
||||
},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 440]],
|
||||
"origin": [["src/views/board/index.tsx", 556]],
|
||||
"translation": "{0} не найдено"
|
||||
},
|
||||
"0xWkkH": {
|
||||
@@ -238,6 +238,13 @@
|
||||
"origin": [["src/views/home/components/Features.tsx", 110]],
|
||||
"translation": "Журналы активности"
|
||||
},
|
||||
"UGCIzB": {
|
||||
"message": "Add / edit label",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 50]],
|
||||
"translation": "Добавить / изменить метку"
|
||||
},
|
||||
"B3xxao": {
|
||||
"message": "Add a card",
|
||||
"placeholders": {},
|
||||
@@ -288,8 +295,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/LabelSelector.tsx", 113],
|
||||
["src/views/card/components/LabelSelector.tsx", 118]
|
||||
["src/views/card/components/LabelSelector.tsx", 114],
|
||||
["src/views/card/components/LabelSelector.tsx", 119]
|
||||
],
|
||||
"translation": "Добавить метку"
|
||||
},
|
||||
@@ -298,7 +305,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 134],
|
||||
["src/views/card/components/MemberSelector.tsx", 135],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 257]
|
||||
],
|
||||
"translation": "Добавить участника"
|
||||
@@ -549,6 +556,13 @@
|
||||
],
|
||||
"translation": "Произошла непредвиденная ошибка. Пожалуйста, попробуйте позже."
|
||||
},
|
||||
"YkfDoz": {
|
||||
"translation": "Ежегодно",
|
||||
"message": "Annual",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 63]]
|
||||
},
|
||||
"3bqt9U": {
|
||||
"message": "Anyone with this link can join your workspace",
|
||||
"placeholders": {},
|
||||
@@ -749,6 +763,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 59]],
|
||||
"translation": "Ожидание клиента"
|
||||
},
|
||||
"iH8pgl": {
|
||||
"translation": "Назад",
|
||||
"message": "Back",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 275]]
|
||||
},
|
||||
"KNKCTb": {
|
||||
"message": "Backlog",
|
||||
"placeholders": {},
|
||||
@@ -791,6 +812,13 @@
|
||||
"origin": [["src/views/pricing/components/PricingTiers.tsx", 53]],
|
||||
"translation": "Лучше всего подходит для небольших и развивающихся команд, которым нужна совместная работа"
|
||||
},
|
||||
"zt/6cS": {
|
||||
"translation": "Идеально для небольших команд, которые хотят сотрудничать и работать быстрее вместе.",
|
||||
"message": "Best for small teams who want to collaborate and move faster together.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 86]]
|
||||
},
|
||||
"qaS+1/": {
|
||||
"message": "Best for teams that want to scale without limits",
|
||||
"placeholders": {},
|
||||
@@ -842,7 +870,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/card/index.tsx", 317],
|
||||
["src/views/public/board/index.tsx", 125]
|
||||
],
|
||||
@@ -1235,12 +1263,14 @@
|
||||
"origin": [
|
||||
["src/components/DeleteLabelConfirmation.tsx", 49],
|
||||
["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 176],
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 267],
|
||||
["src/views/board/components/DeleteBoardConfirmation.tsx", 44],
|
||||
["src/views/card/components/Comment.tsx", 195],
|
||||
["src/views/card/components/DeleteCardConfirmation.tsx", 86],
|
||||
["src/views/card/components/DeleteChecklistConfirmation.tsx", 64],
|
||||
["src/views/card/components/DeleteCommentConfirmation.tsx", 77],
|
||||
["src/views/members/components/DeleteMemberConfirmation.tsx", 55],
|
||||
["src/views/onboarding/select-plan/index.tsx", 209],
|
||||
["src/views/settings/components/Avatar.tsx", 287],
|
||||
["src/views/settings/components/ChangePasswordConfirmation.tsx", 168],
|
||||
[
|
||||
@@ -1261,6 +1291,15 @@
|
||||
"origin": [["src/views/card/index.tsx", 317]],
|
||||
"translation": "Карточка"
|
||||
},
|
||||
"sU2uWc": {
|
||||
"message": "Card duplicated",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 67]
|
||||
],
|
||||
"translation": "Карточка продублирована"
|
||||
},
|
||||
"fEY2vP": {
|
||||
"message": "Card not found",
|
||||
"placeholders": {},
|
||||
@@ -1283,6 +1322,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 307],
|
||||
["src/views/card/components/Dropdown.tsx", 44],
|
||||
["src/views/public/board/CardModal.tsx", 38]
|
||||
],
|
||||
@@ -1360,6 +1400,13 @@
|
||||
],
|
||||
"translation": "Чек-листы"
|
||||
},
|
||||
"zMquA7": {
|
||||
"translation": "Выберите тариф",
|
||||
"message": "Choose a plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 122]]
|
||||
},
|
||||
"VHS0aJ": {
|
||||
"message": "Clear all custom permissions?",
|
||||
"placeholders": {},
|
||||
@@ -1617,6 +1664,16 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 40]],
|
||||
"translation": "Создание контента"
|
||||
},
|
||||
"xGVfLh": {
|
||||
"translation": "Продолжить",
|
||||
"message": "Continue",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 212],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 291]
|
||||
]
|
||||
},
|
||||
"J2Wbjt": {
|
||||
"message": "Continue with ",
|
||||
"placeholders": {},
|
||||
@@ -1661,6 +1718,40 @@
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 58]],
|
||||
"translation": "Скопировать ссылку на карточку"
|
||||
},
|
||||
"0utuU6": {
|
||||
"message": "Copy checklists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 257]
|
||||
],
|
||||
"translation": "Копировать чек-листы"
|
||||
},
|
||||
"fDQ7hA": {
|
||||
"message": "Copy labels",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 221]
|
||||
],
|
||||
"translation": "Копировать метки"
|
||||
},
|
||||
"1bJKhj": {
|
||||
"message": "Copy link to card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 62]],
|
||||
"translation": "Копировать ссылку на карточку"
|
||||
},
|
||||
"uvH2xS": {
|
||||
"message": "Copy members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 239]
|
||||
],
|
||||
"translation": "Копировать участников"
|
||||
},
|
||||
"9PaIxv": {
|
||||
"message": "Core features",
|
||||
"placeholders": {},
|
||||
@@ -1757,7 +1848,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewCardForm.tsx", 417],
|
||||
["src/views/card/components/LabelSelector.tsx", 100]
|
||||
["src/views/card/components/LabelSelector.tsx", 101]
|
||||
],
|
||||
"translation": "Создать новую метку"
|
||||
},
|
||||
@@ -1766,8 +1857,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 76],
|
||||
["src/views/board/index.tsx", 554]
|
||||
["src/views/board/index.tsx", 91],
|
||||
["src/views/board/index.tsx", 670]
|
||||
],
|
||||
"translation": "Создать новый список"
|
||||
},
|
||||
@@ -1791,7 +1882,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 388],
|
||||
["src/components/WorkspaceMenu.tsx", 153]
|
||||
["src/components/WorkspaceMenu.tsx", 160]
|
||||
],
|
||||
"translation": "Создать рабочее пространство"
|
||||
},
|
||||
@@ -1891,6 +1982,13 @@
|
||||
],
|
||||
"translation": "Пользовательское имя"
|
||||
},
|
||||
"ZDPJBc": {
|
||||
"translation": "Для пользовательских имен пользователей требуется обновление до тарифа Pro",
|
||||
"message": "Custom usernames require upgrading to a Pro plan",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 220]]
|
||||
},
|
||||
"j9IZZ0": {
|
||||
"message": "Custom workspace URL",
|
||||
"placeholders": {},
|
||||
@@ -1985,7 +2083,10 @@
|
||||
"message": "Delete card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/Dropdown.tsx", 76]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMenu.tsx", 74],
|
||||
["src/views/card/components/Dropdown.tsx", 76]
|
||||
],
|
||||
"translation": "Удалить карточку"
|
||||
},
|
||||
"njJFtc": {
|
||||
@@ -2171,6 +2272,9 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 36],
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 48],
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 68],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 17],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 23],
|
||||
["src/views/boards/components/TemplateBoards.tsx", 29],
|
||||
@@ -2226,6 +2330,34 @@
|
||||
"origin": [["src/views/board/components/Filters.tsx", 122]],
|
||||
"translation": "Срок — завтра"
|
||||
},
|
||||
"euc6Ns": {
|
||||
"message": "Duplicate",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Дублировать"
|
||||
},
|
||||
"BTDPLo": {
|
||||
"message": "Duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 111],
|
||||
["src/views/board/components/CardContextMenu.tsx", 68]
|
||||
],
|
||||
"translation": "Дублировать карточку"
|
||||
},
|
||||
"06EQqT": {
|
||||
"message": "Duplicating…",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 279]
|
||||
],
|
||||
"translation": "Дублирование…"
|
||||
},
|
||||
"ePK91l": {
|
||||
"message": "Edit",
|
||||
"placeholders": {},
|
||||
@@ -2338,6 +2470,22 @@
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 100]],
|
||||
"translation": "Видимость email"
|
||||
},
|
||||
"bFREhu": {
|
||||
"message": "End of list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 200]
|
||||
],
|
||||
"translation": "Конец списка"
|
||||
},
|
||||
"SUXBxp": {
|
||||
"translation": "Разработка",
|
||||
"message": "Engineering",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"0+ewPp": {
|
||||
"message": "Enhancement",
|
||||
"placeholders": {},
|
||||
@@ -2794,6 +2942,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 77],
|
||||
["src/views/onboarding/select-plan/index.tsx", 78],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 331],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
["src/views/pricing/components/Pricing.tsx", 32],
|
||||
@@ -2894,7 +3044,7 @@
|
||||
"message": "Get started by creating a new list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 539]],
|
||||
"origin": [["src/views/board/index.tsx", 655]],
|
||||
"translation": "Начните с создания нового списка"
|
||||
},
|
||||
"oW13KZ": {
|
||||
@@ -3004,6 +3154,13 @@
|
||||
"origin": [["src/components/SideNavigation.tsx", 119]],
|
||||
"translation": "Перейти к шаблонам"
|
||||
},
|
||||
"SUvm1Y": {
|
||||
"translation": "Подходит для начинающих пользователей, которым нужны только базовые функции.",
|
||||
"message": "Good for individuals starting out who just need the essentials.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 79]]
|
||||
},
|
||||
"cdyS7J": {
|
||||
"message": "Google SSO",
|
||||
"placeholders": {},
|
||||
@@ -3314,7 +3471,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/card/components/MemberSelector.tsx", 114],
|
||||
["src/views/card/components/MemberSelector.tsx", 115],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 367]
|
||||
],
|
||||
"translation": "Пригласить участника"
|
||||
@@ -3386,6 +3543,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextLabelsModal.tsx", 31],
|
||||
["src/views/board/components/Filters.tsx", 155],
|
||||
["src/views/board/components/NewCardForm.tsx", 421],
|
||||
["src/views/card/index.tsx", 133]
|
||||
@@ -3497,6 +3655,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 80],
|
||||
["src/views/board/index.tsx", 305],
|
||||
["src/views/card/components/Dropdown.tsx", 42],
|
||||
["src/views/public/board/CardModal.tsx", 36],
|
||||
["src/views/public/board/index.tsx", 77]
|
||||
@@ -3507,7 +3666,10 @@
|
||||
"message": "List",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/index.tsx", 124]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 117],
|
||||
["src/views/card/index.tsx", 124]
|
||||
],
|
||||
"translation": "Список"
|
||||
},
|
||||
"zQX5Dj": {
|
||||
@@ -3596,6 +3758,16 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 91]],
|
||||
"translation": "Создать шаблон"
|
||||
},
|
||||
"hB02vO": {
|
||||
"message": "Manage members",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextMembersModal.tsx", 51],
|
||||
["src/views/board/components/CardContextMenu.tsx", 38]
|
||||
],
|
||||
"translation": "Управление участниками"
|
||||
},
|
||||
"IDvohQ": {
|
||||
"message": "marked a checklist item as incomplete",
|
||||
"placeholders": {},
|
||||
@@ -3612,6 +3784,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 258]],
|
||||
"translation": "отметил элемент контрольного списка <0>{0}</0> как невыполненный"
|
||||
},
|
||||
"vo2a+a": {
|
||||
"translation": "Маркетинг",
|
||||
"message": "Marketing",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 161]]
|
||||
},
|
||||
"agPptk": {
|
||||
"message": "Medium",
|
||||
"placeholders": {},
|
||||
@@ -3683,6 +3862,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 62],
|
||||
["src/views/pricing/components/Pricing.tsx", 14],
|
||||
["src/views/pricing/index.tsx", 20]
|
||||
],
|
||||
@@ -3695,6 +3875,20 @@
|
||||
"origin": [["src/views/members/components/InviteMemberForm.tsx", 159]],
|
||||
"translation": "ежемесячная оплата"
|
||||
},
|
||||
"51UCsN": {
|
||||
"message": "Move to another list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMenu.tsx", 44]],
|
||||
"translation": "Переместить в другой список"
|
||||
},
|
||||
"J4+OTA": {
|
||||
"message": "Move to list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 70]],
|
||||
"translation": "Переместить в список"
|
||||
},
|
||||
"BOqTi5": {
|
||||
"message": "moved the card from <0>{0}</0> to<1>{1}</1>",
|
||||
"placeholders": {
|
||||
@@ -3806,7 +4000,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/NewListForm.tsx", 113],
|
||||
["src/views/board/index.tsx", 503]
|
||||
["src/views/board/index.tsx", 619]
|
||||
],
|
||||
"translation": "Новый список"
|
||||
},
|
||||
@@ -3932,14 +4126,14 @@
|
||||
"message": "No lists",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 535]],
|
||||
"origin": [["src/views/board/index.tsx", 651]],
|
||||
"translation": "Нет списков"
|
||||
},
|
||||
"fvLNDy": {
|
||||
"message": "No lists have been created yet",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/index.tsx", 540]],
|
||||
"origin": [["src/views/board/index.tsx", 656]],
|
||||
"translation": "Списки ещё не созданы"
|
||||
},
|
||||
"i30J2U": {
|
||||
@@ -4020,7 +4214,7 @@
|
||||
"message": "Open command menu",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 31]],
|
||||
"origin": [["src/components/WorkspaceMenu.tsx", 34]],
|
||||
"translation": "Открыть командное меню"
|
||||
},
|
||||
"cFQEU/": {
|
||||
@@ -4236,6 +4430,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 86]],
|
||||
"translation": "Личный проект"
|
||||
},
|
||||
"Oi+J+N": {
|
||||
"translation": "Выберите тариф, чтобы начать. Все платные тарифы включают 14-дневный бесплатный пробный период.",
|
||||
"message": "Pick a plan to get started. All paid plans include a 14-day free trial.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 125]]
|
||||
},
|
||||
"Iqh0Uv": {
|
||||
"message": "Planned",
|
||||
"placeholders": {},
|
||||
@@ -4331,8 +4532,8 @@
|
||||
["src/views/board/components/NewTemplateForm.tsx", 77],
|
||||
["src/views/board/components/UpdateBoardSlugForm.tsx", 73],
|
||||
["src/views/board/components/VisibilityButton.tsx", 57],
|
||||
["src/views/board/index.tsx", 194],
|
||||
["src/views/board/index.tsx", 250],
|
||||
["src/views/board/index.tsx", 217],
|
||||
["src/views/board/index.tsx", 273],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 243],
|
||||
["src/views/boards/components/ImportBoardsForm.tsx", 395],
|
||||
["src/views/card/components/AttachmentThumbnails.tsx", 74],
|
||||
@@ -4360,6 +4561,8 @@
|
||||
["src/views/members/components/InviteMemberForm.tsx", 104],
|
||||
["src/views/members/components/InviteMemberForm.tsx", 241],
|
||||
["src/views/members/index.tsx", 66],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 101],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 150],
|
||||
["src/views/settings/components/Avatar.tsx", 200],
|
||||
["src/views/settings/components/DeleteAccountConfirmation.tsx", 40],
|
||||
["src/views/settings/components/DeleteWorkspaceConfirmation.tsx", 46],
|
||||
@@ -4387,12 +4590,24 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 76],
|
||||
["src/views/board/components/CardContextMoveListModal.tsx", 42],
|
||||
["src/views/board/index.tsx", 314],
|
||||
["src/views/card/components/Dropdown.tsx", 51],
|
||||
["src/views/public/board/CardModal.tsx", 45],
|
||||
["src/views/public/board/index.tsx", 86]
|
||||
],
|
||||
"translation": "Пожалуйста, попробуйте ещё раз."
|
||||
},
|
||||
"nYNMZZ": {
|
||||
"message": "Position in list (0 = first, leave empty for end)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 193]
|
||||
],
|
||||
"translation": "Позиция в списке (0 = первая, оставьте пустым для конца)"
|
||||
},
|
||||
"aHCEmh": {
|
||||
"message": "Pricing",
|
||||
"placeholders": {},
|
||||
@@ -4438,6 +4653,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 91],
|
||||
["src/views/pricing/components/FeatureComparisonTable.tsx", 333],
|
||||
["src/views/pricing/components/PricingTiers.tsx", 70]
|
||||
],
|
||||
@@ -4695,7 +4911,8 @@
|
||||
"origin": [
|
||||
["src/views/home/components/Footer.tsx", 36],
|
||||
["src/views/home/components/Header.tsx", 13],
|
||||
["src/views/home/components/Header.tsx", 28]
|
||||
["src/views/home/components/Header.tsx", 28],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 161]
|
||||
],
|
||||
"translation": "Дорожная карта"
|
||||
},
|
||||
@@ -4814,6 +5031,15 @@
|
||||
"origin": [["src/views/home/components/Testimonials.tsx", 239]],
|
||||
"translation": "Посмотрите, что наши пользователи говорят о Kan"
|
||||
},
|
||||
"zYRVNp": {
|
||||
"message": "Select a list",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 131]
|
||||
],
|
||||
"translation": "Выберите список"
|
||||
},
|
||||
"wgNoIs": {
|
||||
"message": "Select all",
|
||||
"placeholders": {},
|
||||
@@ -4884,7 +5110,11 @@
|
||||
"message": "Set due date",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/card/components/DueDateSelector.tsx", 121]],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDueDateModal.tsx", 20],
|
||||
["src/views/board/components/CardContextMenu.tsx", 56],
|
||||
["src/views/card/components/DueDateSelector.tsx", 121]
|
||||
],
|
||||
"translation": "Установить срок"
|
||||
},
|
||||
"Eit43O": {
|
||||
@@ -4894,6 +5124,13 @@
|
||||
"origin": [["src/views/card/components/ActivityList.tsx", 142]],
|
||||
"translation": "установить срок"
|
||||
},
|
||||
"JjEJSy": {
|
||||
"translation": "Настройте ваше рабочее пространство",
|
||||
"message": "Set up your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 179]]
|
||||
},
|
||||
"Tz0i8g": {
|
||||
"message": "Settings",
|
||||
"placeholders": {},
|
||||
@@ -4974,6 +5211,16 @@
|
||||
"origin": [["src/views/invite/index.tsx", 154]],
|
||||
"translation": "Войти"
|
||||
},
|
||||
"fcWrnU": {
|
||||
"translation": "Выйти",
|
||||
"message": "Sign out",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/select-plan/index.tsx", 284],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 362]
|
||||
]
|
||||
},
|
||||
"mErq7F": {
|
||||
"message": "Sign Up",
|
||||
"placeholders": {},
|
||||
@@ -5059,6 +5306,13 @@
|
||||
"origin": [["src/views/boards/components/TemplateBoards.tsx", 22]],
|
||||
"translation": "Разработка ПО"
|
||||
},
|
||||
"6sKjjx": {
|
||||
"translation": "Индивидуальный",
|
||||
"message": "Solo",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 76]]
|
||||
},
|
||||
"vnS6Rf": {
|
||||
"message": "SSO",
|
||||
"placeholders": {},
|
||||
@@ -5158,6 +5412,13 @@
|
||||
"origin": [["src/components/UserMenu.tsx", 144]],
|
||||
"translation": "Система"
|
||||
},
|
||||
"KM6m8p": {
|
||||
"translation": "Команда",
|
||||
"message": "Team",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 83]]
|
||||
},
|
||||
"bff61F": {
|
||||
"message": "Team Plan",
|
||||
"placeholders": {},
|
||||
@@ -5184,8 +5445,8 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 449]
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/board/index.tsx", 565]
|
||||
],
|
||||
"translation": "Шаблон"
|
||||
},
|
||||
@@ -5279,6 +5540,15 @@
|
||||
"origin": [["src/views/board/components/BoardDropdown.tsx", 47]],
|
||||
"translation": "Доска была восстановлена из архива."
|
||||
},
|
||||
"nKBUeF": {
|
||||
"message": "The card has been duplicated.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 69]
|
||||
],
|
||||
"translation": "Карточка была продублирована."
|
||||
},
|
||||
"jlB2RY": {
|
||||
"message": "The current password you entered is incorrect.",
|
||||
"placeholders": {},
|
||||
@@ -5401,6 +5671,20 @@
|
||||
],
|
||||
"translation": "Права этого участника были сброшены до значений по умолчанию для его роли."
|
||||
},
|
||||
"HQVm6e": {
|
||||
"translation": "Этот URL уже занят",
|
||||
"message": "This URL has already been taken",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 73]]
|
||||
},
|
||||
"gKmoow": {
|
||||
"translation": "Этот URL зарезервирован",
|
||||
"message": "This URL is reserved",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 75]]
|
||||
},
|
||||
"OAYToL": {
|
||||
"message": "This will remove all custom member permissions in this workspace. Members will inherit permissions only from their roles.",
|
||||
"placeholders": {},
|
||||
@@ -5461,6 +5745,15 @@
|
||||
"origin": [["src/components/YouTubeEmbed/EditYouTubeModal.tsx", 127]],
|
||||
"translation": "Заголовок"
|
||||
},
|
||||
"wK4OTM": {
|
||||
"message": "Title (optional)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 180]
|
||||
],
|
||||
"translation": "Название (необязательно)"
|
||||
},
|
||||
"Se/UIp": {
|
||||
"message": "To Do",
|
||||
"placeholders": {},
|
||||
@@ -5563,6 +5856,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 312],
|
||||
["src/views/card/components/Dropdown.tsx", 49],
|
||||
["src/views/public/board/CardModal.tsx", 43],
|
||||
["src/views/public/board/index.tsx", 84]
|
||||
@@ -5604,7 +5898,10 @@
|
||||
"message": "Unable to create workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 158]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 158],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 100]
|
||||
],
|
||||
"translation": "Не удалось создать рабочую область"
|
||||
},
|
||||
"WHHLh9": {
|
||||
@@ -5644,6 +5941,22 @@
|
||||
"origin": [["src/views/card/components/DeleteCommentConfirmation.tsx", 45]],
|
||||
"translation": "Не удалось удалить комментарий"
|
||||
},
|
||||
"Oo4E6p": {
|
||||
"message": "Unable to duplicate card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/components/CardContextDuplicateModal.tsx", 75]
|
||||
],
|
||||
"translation": "Невозможно дублировать карточку"
|
||||
},
|
||||
"K7k9u3": {
|
||||
"message": "Unable to move card",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/board/components/CardContextMoveListModal.tsx", 41]],
|
||||
"translation": "Невозможно переместить карточку"
|
||||
},
|
||||
"8yFGGF": {
|
||||
"message": "Unable to remove member",
|
||||
"placeholders": {},
|
||||
@@ -5676,6 +5989,13 @@
|
||||
"origin": [["src/components/FeedbackModal.tsx", 40]],
|
||||
"translation": "Не удалось отправить отзыв"
|
||||
},
|
||||
"Q60WUZ": {
|
||||
"translation": "Не удалось начать оформление заказа",
|
||||
"message": "Unable to start checkout",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 149]]
|
||||
},
|
||||
"T7Mywq": {
|
||||
"message": "Unable to update board",
|
||||
"placeholders": {},
|
||||
@@ -5702,7 +6022,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 249],
|
||||
["src/views/board/index.tsx", 272],
|
||||
["src/views/card/index.tsx", 231]
|
||||
],
|
||||
"translation": "Не удалось обновить карточку"
|
||||
@@ -5747,7 +6067,7 @@
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/board/index.tsx", 193],
|
||||
["src/views/board/index.tsx", 216],
|
||||
["src/views/card/components/ListSelector.tsx", 54]
|
||||
],
|
||||
"translation": "Не удалось обновить список"
|
||||
@@ -5883,6 +6203,13 @@
|
||||
],
|
||||
"translation": "Неограниченное количество участников"
|
||||
},
|
||||
"8AwlaR": {
|
||||
"translation": "Неограниченное количество участников и персональное имя рабочего пространства для команд, готовых к масштабированию.",
|
||||
"message": "Unlimited members and a custom workspace username for teams ready to scale.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 94]]
|
||||
},
|
||||
"Ws+3X+": {
|
||||
"message": "Unlimited seats and advanced features for growing teams.",
|
||||
"placeholders": {},
|
||||
@@ -5972,7 +6299,10 @@
|
||||
"message": "Upgrade to Pro ($29/month)",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/components/NewWorkspaceForm.tsx", 373]],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 373],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 243]
|
||||
],
|
||||
"translation": "Перейти на Pro (29 $/месяц)"
|
||||
},
|
||||
"b3Thhd": {
|
||||
@@ -6256,7 +6586,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/SettingsLayout.tsx", 47],
|
||||
["src/views/board/index.tsx", 413],
|
||||
["src/views/board/index.tsx", 529],
|
||||
["src/views/boards/index.tsx", 48],
|
||||
["src/views/members/index.tsx", 258],
|
||||
["src/views/public/board/index.tsx", 125],
|
||||
@@ -6284,7 +6614,10 @@
|
||||
"message": "Workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/settings/WorkspaceSettings.tsx", 82]],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 253],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 82]
|
||||
],
|
||||
"translation": "Описание рабочего пространства"
|
||||
},
|
||||
"Ax/hYa": {
|
||||
@@ -6331,6 +6664,7 @@
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/components/NewWorkspaceForm.tsx", 263],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 188],
|
||||
["src/views/settings/WorkspaceSettings.tsx", 63]
|
||||
],
|
||||
"translation": "Название рабочего пространства"
|
||||
@@ -6438,6 +6772,13 @@
|
||||
"origin": [["src/views/settings/AccountSettings.tsx", 91]],
|
||||
"translation": "Вы собираетесь изменить свой пароль."
|
||||
},
|
||||
"3WXdoZ": {
|
||||
"translation": "Вы всегда можете изменить это позже в настройках.",
|
||||
"message": "You can always change these later in settings.",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 182]]
|
||||
},
|
||||
"aelko+": {
|
||||
"message": "You can get a custom workspace URL, like <0>kan.bn/kan</0>, by going into your <1>workspace settings</1> and purchasing a pro workspace subscription. All subscriptions help fund the development of the project!",
|
||||
"placeholders": {},
|
||||
@@ -6467,8 +6808,8 @@
|
||||
["src/views/board/components/List.tsx", 117],
|
||||
["src/views/board/components/UpdateBoardSlugButton.tsx", 58],
|
||||
["src/views/board/components/VisibilityButton.tsx", 72],
|
||||
["src/views/board/index.tsx", 487],
|
||||
["src/views/board/index.tsx", 545],
|
||||
["src/views/board/index.tsx", 603],
|
||||
["src/views/board/index.tsx", 661],
|
||||
["src/views/boards/components/BoardsList.tsx", 71],
|
||||
["src/views/boards/index.tsx", 59],
|
||||
["src/views/boards/index.tsx", 80]
|
||||
@@ -6533,6 +6874,13 @@
|
||||
],
|
||||
"translation": "Ваш аккаунт был удалён."
|
||||
},
|
||||
"c4nMcR": {
|
||||
"translation": "Ваш аватар",
|
||||
"message": "Your avatar",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/select-plan/index.tsx", 229]]
|
||||
},
|
||||
"evg7+A": {
|
||||
"message": "Your boards have been imported.",
|
||||
"placeholders": {},
|
||||
@@ -6619,6 +6967,20 @@
|
||||
"origin": [["src/pages/unsubscribe/index.tsx", 33]],
|
||||
"translation": "В вашей ссылке для отписки отсутствует токен. Пожалуйста, откройте последнее письмо и попробуйте снова."
|
||||
},
|
||||
"GRAGsB": {
|
||||
"translation": "Ваше рабочее пространство",
|
||||
"message": "Your workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 322]]
|
||||
},
|
||||
"j0o6ml": {
|
||||
"translation": "Описание вашего рабочего пространства",
|
||||
"message": "Your workspace description",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [["src/views/onboarding/workspace-details/index.tsx", 325]]
|
||||
},
|
||||
"GnSSGm": {
|
||||
"message": "Your workspace description has been updated.",
|
||||
"placeholders": {},
|
||||
@@ -6655,6 +7017,16 @@
|
||||
],
|
||||
"translation": "Слаг вашего рабочего пространства был обновлён."
|
||||
},
|
||||
"OTxjpR": {
|
||||
"translation": "your-workspace",
|
||||
"message": "your-workspace",
|
||||
"placeholders": {},
|
||||
"comments": [],
|
||||
"origin": [
|
||||
["src/views/onboarding/workspace-details/index.tsx", 197],
|
||||
["src/views/onboarding/workspace-details/index.tsx", 198]
|
||||
]
|
||||
},
|
||||
"4DOCMI": {
|
||||
"message": "YouTube URL",
|
||||
"placeholders": {},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,12 +1,13 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { withApiLogging } from "@kan/api/utils/apiLogging";
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
|
||||
import { env } from "~/env";
|
||||
|
||||
export default withRateLimit(
|
||||
{ points: 100, duration: 60 },
|
||||
async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
withApiLogging(async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(405).json({ message: "Method not allowed" });
|
||||
}
|
||||
@@ -32,7 +33,9 @@ export default withRateLimit(
|
||||
try {
|
||||
allowedHost = new URL(s3Endpoint).hostname.toLowerCase();
|
||||
} catch {
|
||||
return res.status(500).json({ message: "Storage endpoint misconfigured" });
|
||||
return res
|
||||
.status(500)
|
||||
.json({ message: "Storage endpoint misconfigured" });
|
||||
}
|
||||
|
||||
if (hostname !== allowedHost && !hostname.endsWith(`.${allowedHost}`)) {
|
||||
@@ -66,10 +69,7 @@ export default withRateLimit(
|
||||
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" });
|
||||
return res.status(500).json({ message: "Failed to download attachment" });
|
||||
}
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { withApiLogging } from "@kan/api/utils/apiLogging";
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
|
||||
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" });
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch("https://formbricks.com/api/oss-friends");
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch from Formbricks");
|
||||
withApiLogging(async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(405).json({ message: "Method not allowed" });
|
||||
}
|
||||
const data = await response.json();
|
||||
|
||||
return res.status(200).json(data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching OSS friends:", error);
|
||||
return res.status(500).json({ message: "Failed to fetch OSS friends" });
|
||||
}
|
||||
},
|
||||
try {
|
||||
const response = await fetch("https://formbricks.com/api/oss-friends");
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch from Formbricks");
|
||||
}
|
||||
const data = await response.json();
|
||||
|
||||
return res.status(200).json(data);
|
||||
} catch (error) {
|
||||
return res.status(500).json({ message: "Failed to fetch OSS friends" });
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -2,34 +2,34 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { env } from "next-runtime-env";
|
||||
|
||||
import { createNextApiContext } from "@kan/api/trpc";
|
||||
import { createStripeClient } from "@kan/stripe";
|
||||
import { withApiLogging } from "@kan/api/utils/apiLogging";
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
import { createStripeClient } from "@kan/stripe";
|
||||
|
||||
export default withRateLimit(
|
||||
{ points: 100, duration: 60 },
|
||||
async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const stripe = createStripeClient();
|
||||
withApiLogging(async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const stripe = createStripeClient();
|
||||
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ error: "Method not allowed" });
|
||||
}
|
||||
|
||||
try {
|
||||
const { user } = await createNextApiContext(req);
|
||||
|
||||
if (!user?.stripeCustomerId) {
|
||||
return res.status(404).json({ error: "No billing account found" });
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ error: "Method not allowed" });
|
||||
}
|
||||
|
||||
const session = await stripe.billingPortal.sessions.create({
|
||||
customer: user.stripeCustomerId,
|
||||
return_url: `${env("NEXT_PUBLIC_BASE_URL")}/settings`,
|
||||
});
|
||||
try {
|
||||
const { user } = await createNextApiContext(req);
|
||||
|
||||
return res.status(200).json({ url: session.url });
|
||||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
return res.status(500).json({ error: "Error creating portal session" });
|
||||
}
|
||||
},
|
||||
if (!user?.stripeCustomerId) {
|
||||
return res.status(404).json({ error: "No billing account found" });
|
||||
}
|
||||
|
||||
const session = await stripe.billingPortal.sessions.create({
|
||||
customer: user.stripeCustomerId,
|
||||
return_url: `${env("NEXT_PUBLIC_BASE_URL")}/settings`,
|
||||
});
|
||||
|
||||
return res.status(200).json({ url: session.url });
|
||||
} catch (error) {
|
||||
return res.status(500).json({ error: "Error creating portal session" });
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -3,10 +3,13 @@ import { env } from "next-runtime-env";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createNextApiContext } from "@kan/api/trpc";
|
||||
import { withApiLogging } from "@kan/api/utils/apiLogging";
|
||||
import { assertPermission } from "@kan/api/utils/permissions";
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
import * as subscriptionRepo from "@kan/db/repository/subscription.repo";
|
||||
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
import { generateUID } from "@kan/shared/utils";
|
||||
import { createStripeClient } from "@kan/stripe";
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
|
||||
const workspaceSlugSchema = z
|
||||
.string()
|
||||
@@ -17,21 +20,24 @@ const workspaceSlugSchema = z
|
||||
interface CheckoutSessionRequest {
|
||||
successUrl: string;
|
||||
cancelUrl: string;
|
||||
slug: string;
|
||||
workspacePublicId: string;
|
||||
stripeCustomerId: string;
|
||||
plan: "team" | "pro";
|
||||
billing?: string;
|
||||
workspacePublicId?: string;
|
||||
slug?: string;
|
||||
workspaceName?: string;
|
||||
workspaceDescription?: string;
|
||||
workspaceSlug?: string;
|
||||
}
|
||||
|
||||
export default withRateLimit(
|
||||
{ points: 100, duration: 60 },
|
||||
async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const stripe = createStripeClient();
|
||||
withApiLogging(async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const stripe = createStripeClient();
|
||||
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ error: "Method not allowed" });
|
||||
}
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ error: "Method not allowed" });
|
||||
}
|
||||
|
||||
try {
|
||||
const { user, db } = await createNextApiContext(req);
|
||||
|
||||
if (!user) {
|
||||
@@ -39,81 +45,107 @@ export default withRateLimit(
|
||||
}
|
||||
|
||||
const body = req.body as CheckoutSessionRequest;
|
||||
const { successUrl, cancelUrl, slug, workspacePublicId } = body;
|
||||
const {
|
||||
successUrl,
|
||||
cancelUrl,
|
||||
plan,
|
||||
billing,
|
||||
workspacePublicId,
|
||||
slug,
|
||||
workspaceName,
|
||||
workspaceDescription,
|
||||
workspaceSlug,
|
||||
} = body;
|
||||
|
||||
if (!successUrl || !cancelUrl || !workspacePublicId) {
|
||||
if (!successUrl || !cancelUrl || !plan) {
|
||||
return res.status(400).json({ error: "Missing required fields" });
|
||||
}
|
||||
|
||||
if (slug) {
|
||||
const slugResult = workspaceSlugSchema.safeParse(slug);
|
||||
if (!workspacePublicId && !workspaceName) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: "Must provide workspacePublicId or workspaceName" });
|
||||
}
|
||||
|
||||
const resolvedSlug = slug ?? workspaceSlug;
|
||||
|
||||
if (resolvedSlug) {
|
||||
const slugResult = workspaceSlugSchema.safeParse(resolvedSlug);
|
||||
if (!slugResult.success) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Invalid workspace slug" }),
|
||||
{
|
||||
status: 400,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
},
|
||||
);
|
||||
return res.status(400).json({ error: "Invalid workspace slug" });
|
||||
}
|
||||
}
|
||||
|
||||
const workspace = await workspaceRepo.getAllByUserId(db, user.id);
|
||||
let resolvedWorkspacePublicId = workspacePublicId;
|
||||
let subscriptionId: number | undefined;
|
||||
|
||||
const isMemberOfWorkspace = workspace.some(
|
||||
({ workspace }) => workspace.publicId === body.workspacePublicId,
|
||||
);
|
||||
if (workspacePublicId) {
|
||||
// Existing workspace upgrade
|
||||
const workspace = await workspaceRepo.getByPublicId(
|
||||
db,
|
||||
workspacePublicId,
|
||||
);
|
||||
|
||||
if (!isMemberOfWorkspace) {
|
||||
return new Response(JSON.stringify({ error: "Unauthorized" }), {
|
||||
status: 403,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
if (!workspace) {
|
||||
return res.status(404).json({ error: "Workspace not found" });
|
||||
}
|
||||
|
||||
try {
|
||||
await assertPermission(db, user.id, workspace.id, "workspace:manage");
|
||||
} catch {
|
||||
return res.status(403).json({ error: "Unauthorized" });
|
||||
}
|
||||
|
||||
const subscription = await subscriptionRepo.create(db, {
|
||||
plan: plan,
|
||||
referenceId: workspacePublicId,
|
||||
userId: user.id,
|
||||
stripeCustomerId: user.stripeCustomerId ?? "",
|
||||
status: "incomplete",
|
||||
});
|
||||
|
||||
subscriptionId = subscription?.id;
|
||||
|
||||
if (!subscriptionId) {
|
||||
return res.status(500).json({ error: "Error creating subscription" });
|
||||
}
|
||||
} else {
|
||||
resolvedWorkspacePublicId = generateUID();
|
||||
}
|
||||
|
||||
const subscription = await subscriptionRepo.create(db, {
|
||||
plan: "pro",
|
||||
referenceId: workspacePublicId,
|
||||
userId: user.id,
|
||||
stripeCustomerId: user.stripeCustomerId ?? "",
|
||||
status: "incomplete",
|
||||
});
|
||||
|
||||
const subscriptionId = subscription?.id;
|
||||
|
||||
if (!subscriptionId) {
|
||||
return res.status(500).json({ error: "Error creating subscription" });
|
||||
}
|
||||
const isTeam = body.plan === "team";
|
||||
const annualPriceId = isTeam
|
||||
? (process.env.STRIPE_TEAM_PLAN_YEARLY_PRICE_ID ??
|
||||
process.env.STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID)
|
||||
: (process.env.STRIPE_PRO_PLAN_YEARLY_PRICE_ID ??
|
||||
process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID);
|
||||
const monthlyPriceId = isTeam
|
||||
? process.env.STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID
|
||||
: process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID;
|
||||
const priceId = billing === "annual" ? annualPriceId : monthlyPriceId;
|
||||
|
||||
const session = await stripe.checkout.sessions.create({
|
||||
mode: "subscription",
|
||||
payment_method_collection: "always",
|
||||
line_items: [
|
||||
{
|
||||
price: process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
subscription_data: {
|
||||
trial_period_days: 14,
|
||||
},
|
||||
success_url: `${env("NEXT_PUBLIC_BASE_URL")}${successUrl}`,
|
||||
line_items: [{ price: priceId, quantity: 1 }],
|
||||
subscription_data: { trial_period_days: 14 },
|
||||
success_url: `${env("NEXT_PUBLIC_BASE_URL")}${successUrl}?workspacePublicId=${resolvedWorkspacePublicId}`,
|
||||
cancel_url: `${env("NEXT_PUBLIC_BASE_URL")}${cancelUrl}`,
|
||||
client_reference_id: workspacePublicId,
|
||||
client_reference_id: resolvedWorkspacePublicId,
|
||||
customer: user.stripeCustomerId ?? undefined,
|
||||
metadata: {
|
||||
...(slug && { workspaceSlug: slug }),
|
||||
workspacePublicId,
|
||||
workspacePublicId: resolvedWorkspacePublicId!,
|
||||
userId: user.id,
|
||||
subscriptionId,
|
||||
userEmail: user.email ?? "",
|
||||
...(resolvedSlug && { workspaceSlug: resolvedSlug }),
|
||||
...(workspaceName && { workspaceName }),
|
||||
...(workspaceDescription && { workspaceDescription }),
|
||||
...(subscriptionId && { subscriptionId: String(subscriptionId) }),
|
||||
plan: plan,
|
||||
isNewWorkspace: workspaceName ? "true" : "false",
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(200).json({ url: session.url });
|
||||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
return res.status(500).json({ error: "Error creating checkout session" });
|
||||
}
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { randomUUID } from "crypto";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import type { Readable } from "node:stream";
|
||||
|
||||
import { createNextApiContext } from "@kan/api/trpc";
|
||||
import * as subscriptionRepo from "@kan/db/repository/subscription.repo";
|
||||
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
import { createLogger } from "@kan/logger";
|
||||
import { createStripeClient } from "@kan/stripe";
|
||||
|
||||
const log = createLogger("stripe-webhook");
|
||||
const log = createLogger("api");
|
||||
|
||||
async function buffer(readable: Readable) {
|
||||
const chunks = [];
|
||||
@@ -21,6 +23,9 @@ export default async function handler(
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
const stripe = createStripeClient();
|
||||
const start = Date.now();
|
||||
const requestId = randomUUID();
|
||||
const procedure = req.url?.split("?")[0] ?? "/api/stripe/webhook";
|
||||
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ message: "Method not allowed" });
|
||||
@@ -44,29 +49,85 @@ export default async function handler(
|
||||
|
||||
const { db } = await createNextApiContext(req);
|
||||
|
||||
log.info({ eventType: event.type, eventId: event.id }, "Stripe webhook received");
|
||||
|
||||
switch (event.type) {
|
||||
case "checkout.session.completed": {
|
||||
const checkoutSession = event.data.object;
|
||||
const meta = checkoutSession.metadata;
|
||||
|
||||
const metaData = checkoutSession.metadata;
|
||||
if (!meta?.workspacePublicId) break;
|
||||
|
||||
if (metaData?.workspacePublicId) {
|
||||
await workspaceRepo.update(db, metaData.workspacePublicId, {
|
||||
...(metaData.workspaceSlug && { slug: metaData.workspaceSlug }),
|
||||
plan: "pro",
|
||||
const plan = meta.plan === "team" ? "team" : ("pro" as const);
|
||||
|
||||
if (
|
||||
meta.isNewWorkspace === "true" &&
|
||||
meta.workspaceName &&
|
||||
meta.userId &&
|
||||
meta.userEmail
|
||||
) {
|
||||
const existing = await workspaceRepo.getByPublicId(db, meta.workspacePublicId);
|
||||
|
||||
if (!existing) {
|
||||
const slug = meta.workspaceSlug ?? meta.workspacePublicId;
|
||||
|
||||
await workspaceRepo.create(db, {
|
||||
publicId: meta.workspacePublicId,
|
||||
name: meta.workspaceName,
|
||||
slug,
|
||||
plan,
|
||||
createdBy: meta.userId,
|
||||
createdByEmail: meta.userEmail,
|
||||
...(meta.workspaceDescription && {
|
||||
description: meta.workspaceDescription,
|
||||
}),
|
||||
});
|
||||
|
||||
await subscriptionRepo.create(db, {
|
||||
plan,
|
||||
referenceId: meta.workspacePublicId,
|
||||
userId: meta.userId,
|
||||
stripeCustomerId: checkoutSession.customer as string,
|
||||
status: "active",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Existing workspace upgrade — update plan (and slug for pro)
|
||||
await workspaceRepo.update(db, meta.workspacePublicId, {
|
||||
plan,
|
||||
...(plan === "pro" && meta.workspaceSlug && { slug: meta.workspaceSlug }),
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log.warn({ eventType: event.type }, "Unhandled Stripe event type");
|
||||
}
|
||||
|
||||
log.info(
|
||||
{
|
||||
requestId,
|
||||
procedure,
|
||||
transport: "rest",
|
||||
duration: Date.now() - start,
|
||||
status: 200,
|
||||
input: { eventType: event.type, eventId: event.id },
|
||||
},
|
||||
"API OK",
|
||||
);
|
||||
|
||||
return res.status(200).json({ received: true });
|
||||
} catch (err) {
|
||||
log.error({ err }, "Stripe webhook handler failed");
|
||||
log.error(
|
||||
{
|
||||
requestId,
|
||||
procedure,
|
||||
transport: "rest",
|
||||
duration: Date.now() - start,
|
||||
status: 400,
|
||||
err,
|
||||
},
|
||||
"API error",
|
||||
);
|
||||
return res.status(400).json({ message: "Webhook handler failed" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,58 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { addYears } from "date-fns";
|
||||
|
||||
import { createNextApiContext } from "@kan/api/trpc";
|
||||
import { integrations } from "@kan/db/schema";
|
||||
import { addYears } from "date-fns";
|
||||
import { withApiLogging } from "@kan/api/utils/apiLogging";
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
import { integrations } from "@kan/db/schema";
|
||||
|
||||
export default withRateLimit(
|
||||
{ points: 100, duration: 60 },
|
||||
async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ message: "Method not allowed" });
|
||||
}
|
||||
withApiLogging(async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ message: "Method not allowed" });
|
||||
}
|
||||
|
||||
const { user } = await createNextApiContext(req);
|
||||
const { user } = await createNextApiContext(req);
|
||||
|
||||
if (!user)
|
||||
return res.status(401).json({ message: "User not authenticated" });
|
||||
if (!user)
|
||||
return res.status(401).json({ message: "User not authenticated" });
|
||||
|
||||
const apiKey = process.env.TRELLO_APP_API_KEY;
|
||||
const apiKey = process.env.TRELLO_APP_API_KEY;
|
||||
|
||||
if (!apiKey)
|
||||
return res.status(500).json({ message: "Trello API key not set in Environment Variables" });
|
||||
if (!apiKey)
|
||||
return res
|
||||
.status(500)
|
||||
.json({ message: "Trello API key not set in Environment Variables" });
|
||||
|
||||
const token = req.body.token;
|
||||
const token = req.body.token;
|
||||
|
||||
if (!token)
|
||||
return res.status(400).json({ message: "No token found" });
|
||||
if (!token) return res.status(400).json({ message: "No token found" });
|
||||
|
||||
try {
|
||||
const { db } = await createNextApiContext(req);
|
||||
try {
|
||||
const { db } = await createNextApiContext(req);
|
||||
|
||||
await db.insert(integrations).values({
|
||||
provider: "trello",
|
||||
userId: user.id,
|
||||
accessToken: token,
|
||||
expiresAt: addYears(new Date(), 1),
|
||||
}).onConflictDoUpdate({
|
||||
set: {
|
||||
accessToken: token,
|
||||
expiresAt: addYears(new Date(), 1),
|
||||
},
|
||||
target: [integrations.userId, integrations.provider],
|
||||
});
|
||||
await db
|
||||
.insert(integrations)
|
||||
.values({
|
||||
provider: "trello",
|
||||
userId: user.id,
|
||||
accessToken: token,
|
||||
expiresAt: addYears(new Date(), 1),
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
set: {
|
||||
accessToken: token,
|
||||
expiresAt: addYears(new Date(), 1),
|
||||
},
|
||||
target: [integrations.userId, integrations.provider],
|
||||
});
|
||||
|
||||
return res.status(200).json({ message: "Trello authentication successful" });
|
||||
} catch (err) {
|
||||
console.error("Trello authentication error:", err);
|
||||
return res.status(400).json({ message: "Trello authentication failed" });
|
||||
}
|
||||
},
|
||||
);
|
||||
return res
|
||||
.status(200)
|
||||
.json({ message: "Trello authentication successful" });
|
||||
} catch (err) {
|
||||
return res.status(400).json({ message: "Trello authentication failed" });
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -3,9 +3,11 @@ import { Novu } from "@novu/api";
|
||||
import { jwtVerify } from "jose";
|
||||
import { z } from "zod";
|
||||
|
||||
import { env } from "~/env";
|
||||
import { withApiLogging } from "@kan/api/utils/apiLogging";
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
|
||||
import { env } from "~/env";
|
||||
|
||||
const requestSchema = z.object({
|
||||
token: z.string().min(1),
|
||||
});
|
||||
@@ -22,84 +24,85 @@ const textEncoder = new TextEncoder();
|
||||
|
||||
export default withRateLimit(
|
||||
{ points: 100, duration: 60 },
|
||||
async (req: NextApiRequest, res: NextApiResponse<ResponseData>) => {
|
||||
if (process.env.NEXT_PUBLIC_KAN_ENV !== "cloud") {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: "Unsubscribe endpoint is not available.",
|
||||
code: "UNAVAILABLE",
|
||||
});
|
||||
}
|
||||
withApiLogging(
|
||||
async (req: NextApiRequest, res: NextApiResponse<ResponseData>) => {
|
||||
if (process.env.NEXT_PUBLIC_KAN_ENV !== "cloud") {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: "Unsubscribe endpoint is not available.",
|
||||
code: "UNAVAILABLE",
|
||||
});
|
||||
}
|
||||
|
||||
if (req.method !== "POST") {
|
||||
res.setHeader("Allow", "POST");
|
||||
return res.status(405).json({
|
||||
success: false,
|
||||
error: "Method not allowed.",
|
||||
code: "METHOD_NOT_ALLOWED",
|
||||
});
|
||||
}
|
||||
if (req.method !== "POST") {
|
||||
res.setHeader("Allow", "POST");
|
||||
return res.status(405).json({
|
||||
success: false,
|
||||
error: "Method not allowed.",
|
||||
code: "METHOD_NOT_ALLOWED",
|
||||
});
|
||||
}
|
||||
|
||||
const parsedBody = requestSchema.safeParse(req.body);
|
||||
const parsedBody = requestSchema.safeParse(req.body);
|
||||
|
||||
if (!parsedBody.success) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: "Invalid request payload.",
|
||||
code: "BAD_REQUEST",
|
||||
});
|
||||
}
|
||||
if (!parsedBody.success) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: "Invalid request payload.",
|
||||
code: "BAD_REQUEST",
|
||||
});
|
||||
}
|
||||
|
||||
if (!env.EMAIL_UNSUBSCRIBE_SECRET || !env.NOVU_API_KEY) {
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
error: "Unsubscribe service is not configured.",
|
||||
code: "NOT_CONFIGURED",
|
||||
});
|
||||
}
|
||||
if (!env.EMAIL_UNSUBSCRIBE_SECRET || !env.NOVU_API_KEY) {
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
error: "Unsubscribe service is not configured.",
|
||||
code: "NOT_CONFIGURED",
|
||||
});
|
||||
}
|
||||
|
||||
let payload: z.infer<typeof tokenPayloadSchema>;
|
||||
let payload: z.infer<typeof tokenPayloadSchema>;
|
||||
|
||||
try {
|
||||
const verified = await jwtVerify(
|
||||
parsedBody.data.token,
|
||||
textEncoder.encode(env.EMAIL_UNSUBSCRIBE_SECRET),
|
||||
{
|
||||
// We intentionally do not use exp/iat claims –
|
||||
// tokens are long-lived and validated only by signature + payload.
|
||||
clockTolerance: "0s",
|
||||
},
|
||||
);
|
||||
payload = tokenPayloadSchema.parse(verified.payload);
|
||||
} catch {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
error: "Your unsubscribe link is invalid or has expired.",
|
||||
code: "INVALID_TOKEN",
|
||||
});
|
||||
}
|
||||
try {
|
||||
const verified = await jwtVerify(
|
||||
parsedBody.data.token,
|
||||
textEncoder.encode(env.EMAIL_UNSUBSCRIBE_SECRET),
|
||||
{
|
||||
// We intentionally do not use exp/iat claims –
|
||||
// tokens are long-lived and validated only by signature + payload.
|
||||
clockTolerance: "0s",
|
||||
},
|
||||
);
|
||||
payload = tokenPayloadSchema.parse(verified.payload);
|
||||
} catch {
|
||||
return res.status(401).json({
|
||||
success: false,
|
||||
error: "Your unsubscribe link is invalid or has expired.",
|
||||
code: "INVALID_TOKEN",
|
||||
});
|
||||
}
|
||||
|
||||
const novu = new Novu({ secretKey: env.NOVU_API_KEY });
|
||||
const novu = new Novu({ secretKey: env.NOVU_API_KEY });
|
||||
|
||||
try {
|
||||
await novu.subscribers.preferences.update(
|
||||
{
|
||||
channels: {
|
||||
email: false,
|
||||
},
|
||||
},
|
||||
payload.subscriberId,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Failed to update Novu preferences", error);
|
||||
return res.status(502).json({
|
||||
success: false,
|
||||
error:
|
||||
"We could not update your email preferences right now. Please try again later.",
|
||||
code: "NOVU_ERROR",
|
||||
});
|
||||
}
|
||||
try {
|
||||
await novu.subscribers.preferences.update(
|
||||
{
|
||||
channels: {
|
||||
email: false,
|
||||
},
|
||||
},
|
||||
payload.subscriberId,
|
||||
);
|
||||
} catch (error) {
|
||||
return res.status(502).json({
|
||||
success: false,
|
||||
error:
|
||||
"We could not update your email preferences right now. Please try again later.",
|
||||
code: "NOVU_ERROR",
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).json({ success: true });
|
||||
},
|
||||
return res.status(200).json({ success: true });
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { Upload } from "@aws-sdk/lib-storage";
|
||||
|
||||
import { createNextApiContext } from "@kan/api/trpc";
|
||||
import { withApiLogging } from "@kan/api/utils/apiLogging";
|
||||
import { assertPermission } from "@kan/api/utils/permissions";
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
import * as cardRepo from "@kan/db/repository/card.repo";
|
||||
@@ -22,7 +23,7 @@ export const config = {
|
||||
|
||||
export default withRateLimit(
|
||||
{ points: 100, duration: 60 },
|
||||
async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
withApiLogging(async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ error: "Method not allowed" });
|
||||
}
|
||||
@@ -36,7 +37,9 @@ export default withRateLimit(
|
||||
|
||||
const bucket = env.NEXT_PUBLIC_ATTACHMENTS_BUCKET_NAME;
|
||||
if (!bucket) {
|
||||
return res.status(500).json({ error: "Attachments bucket not configured" });
|
||||
return res
|
||||
.status(500)
|
||||
.json({ error: "Attachments bucket not configured" });
|
||||
}
|
||||
|
||||
const cardPublicId = req.query.cardPublicId;
|
||||
@@ -55,7 +58,9 @@ export default withRateLimit(
|
||||
}
|
||||
|
||||
if (!Number.isFinite(contentLength) || contentLength <= 0) {
|
||||
return res.status(400).json({ error: "Missing or invalid content length" });
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: "Missing or invalid content length" });
|
||||
}
|
||||
|
||||
if (contentLength > MAX_SIZE_BYTES) {
|
||||
@@ -129,8 +134,7 @@ export default withRateLimit(
|
||||
|
||||
return res.status(200).json({ attachment });
|
||||
} catch (error) {
|
||||
console.error("Attachment upload failed", error);
|
||||
return res.status(500).json({ error: "Internal server error" });
|
||||
}
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -2,13 +2,17 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { PutObjectCommand } from "@aws-sdk/client-s3";
|
||||
|
||||
import { createNextApiContext } from "@kan/api/trpc";
|
||||
import * as userRepo from "@kan/db/repository/user.repo";
|
||||
|
||||
import { env } from "~/env";
|
||||
import { withApiLogging } from "@kan/api/utils/apiLogging";
|
||||
import { withRateLimit } from "@kan/api/utils/rateLimit";
|
||||
import * as userRepo from "@kan/db/repository/user.repo";
|
||||
import { createS3Client } from "@kan/shared/utils";
|
||||
|
||||
const MAX_SIZE_BYTES = parseInt(process.env.S3_AVATAR_UPLOAD_LIMIT || '2097152', 10); // Default 2MB
|
||||
import { env } from "~/env";
|
||||
|
||||
const MAX_SIZE_BYTES = parseInt(
|
||||
process.env.S3_AVATAR_UPLOAD_LIMIT || "2097152",
|
||||
10,
|
||||
); // Default 2MB
|
||||
const allowedContentTypes = ["image/jpeg", "image/png", "image/webp"];
|
||||
|
||||
export const config = {
|
||||
@@ -19,7 +23,7 @@ export const config = {
|
||||
|
||||
export default withRateLimit(
|
||||
{ points: 100, duration: 60 },
|
||||
async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
withApiLogging(async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({ error: "Method not allowed" });
|
||||
}
|
||||
@@ -51,7 +55,9 @@ export default withRateLimit(
|
||||
}
|
||||
|
||||
if (!Number.isFinite(contentLength) || contentLength <= 0) {
|
||||
return res.status(400).json({ error: "Missing or invalid content length" });
|
||||
return res
|
||||
.status(400)
|
||||
.json({ error: "Missing or invalid content length" });
|
||||
}
|
||||
|
||||
if (contentLength > MAX_SIZE_BYTES) {
|
||||
@@ -93,9 +99,7 @@ export default withRateLimit(
|
||||
user: updatedUser,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Avatar upload failed", error);
|
||||
return res.status(500).json({ error: "Internal server error" });
|
||||
}
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
31
apps/web/src/pages/onboarding/select-plan.tsx
Normal file
31
apps/web/src/pages/onboarding/select-plan.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { env } from "next-runtime-env";
|
||||
|
||||
import { authClient } from "@kan/auth/client";
|
||||
|
||||
import { PageHead } from "~/components/PageHead";
|
||||
import SelectPlanView from "~/views/onboarding/select-plan";
|
||||
|
||||
export default function SelectPlanPage() {
|
||||
const router = useRouter();
|
||||
const { data: session, isPending } = authClient.useSession();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPending && !session?.user) {
|
||||
router.push("/login");
|
||||
}
|
||||
if (!isPending && env("NEXT_PUBLIC_KAN_ENV") !== "cloud") {
|
||||
router.push("/boards");
|
||||
}
|
||||
}, [session, isPending, router]);
|
||||
|
||||
if (isPending || !session?.user) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHead title="Select plan | kan.bn" />
|
||||
<SelectPlanView />
|
||||
</>
|
||||
);
|
||||
}
|
||||
28
apps/web/src/pages/onboarding/workspace.tsx
Normal file
28
apps/web/src/pages/onboarding/workspace.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { useRouter } from "next/navigation";
|
||||
import { env } from "next-runtime-env";
|
||||
import { useEffect } from "react";
|
||||
|
||||
import { authClient } from "@kan/auth/client";
|
||||
|
||||
import { PageHead } from "~/components/PageHead";
|
||||
import WorkspaceDetailsView from "~/views/onboarding/workspace-details";
|
||||
|
||||
export default function WorkspaceDetailsPage() {
|
||||
const router = useRouter();
|
||||
const { data: session, isPending } = authClient.useSession();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPending && !session?.user) router.push("/login");
|
||||
if (!isPending && env("NEXT_PUBLIC_KAN_ENV") !== "cloud")
|
||||
router.push("/boards");
|
||||
}, [session, isPending, router]);
|
||||
|
||||
if (isPending || !session?.user) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHead title="Create workspace | kan.bn" />
|
||||
<WorkspaceDetailsView />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -17,7 +17,7 @@ interface Workspace {
|
||||
description: string | null | undefined;
|
||||
publicId: string;
|
||||
slug: string | undefined;
|
||||
plan: "free" | "pro" | "enterprise" | undefined;
|
||||
plan: "free" | "team" | "pro" | "enterprise" | undefined;
|
||||
role: "admin" | "member" | "guest";
|
||||
weekStartDay: 0 | 1 | 6;
|
||||
}
|
||||
@@ -27,7 +27,7 @@ const initialWorkspace: Workspace = {
|
||||
description: null,
|
||||
publicId: "",
|
||||
slug: "",
|
||||
plan: "free",
|
||||
plan: "free" as const,
|
||||
role: "member",
|
||||
weekStartDay: 1,
|
||||
};
|
||||
@@ -50,7 +50,15 @@ export const WorkspaceProvider: React.FC<{ children: ReactNode }> = ({
|
||||
|
||||
const workspacePublicId = useSearchParams().get("workspacePublicId");
|
||||
|
||||
const { data, isLoading } = api.workspace.all.useQuery();
|
||||
const [pendingWorkspaceId, setPendingWorkspaceId] = useState<string | null>(
|
||||
workspacePublicId,
|
||||
);
|
||||
const pollAttemptsRef = React.useRef(0);
|
||||
const MAX_POLL_ATTEMPTS = 5;
|
||||
|
||||
const { data, isLoading } = api.workspace.all.useQuery(undefined, {
|
||||
refetchInterval: pendingWorkspaceId ? 2000 : false,
|
||||
});
|
||||
const utils = api.useUtils();
|
||||
|
||||
const switchWorkspace = (_workspace: Workspace) => {
|
||||
@@ -94,7 +102,16 @@ export const WorkspaceProvider: React.FC<{ children: ReactNode }> = ({
|
||||
({ workspace }) => workspace.publicId === storedWorkspaceId,
|
||||
);
|
||||
|
||||
if (!selectedWorkspace?.workspace) return;
|
||||
if (!selectedWorkspace?.workspace) {
|
||||
pollAttemptsRef.current += 1;
|
||||
if (pollAttemptsRef.current >= MAX_POLL_ATTEMPTS) {
|
||||
setPendingWorkspaceId(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
pollAttemptsRef.current = 0;
|
||||
setPendingWorkspaceId(null);
|
||||
|
||||
setWorkspace({
|
||||
publicId: selectedWorkspace.workspace.publicId,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { env } from "next-runtime-env";
|
||||
|
||||
export const formatToArray = (
|
||||
value: string | string[] | undefined,
|
||||
): string[] => {
|
||||
@@ -50,5 +52,21 @@ export const getAvatarUrl = (imageOrKey: string | null) => {
|
||||
return imageOrKey;
|
||||
}
|
||||
|
||||
// Construct URL from S3 key
|
||||
const useVirtualHosted = env("NEXT_PUBLIC_USE_VIRTUAL_HOSTED_URLS") === "true";
|
||||
const storageDomain = env("NEXT_PUBLIC_STORAGE_DOMAIN");
|
||||
const storageUrl = env("NEXT_PUBLIC_STORAGE_URL");
|
||||
const bucket = env("NEXT_PUBLIC_AVATAR_BUCKET_NAME");
|
||||
|
||||
if (useVirtualHosted && storageDomain && bucket) {
|
||||
// Virtual-hosted style: https://{bucket}.{domain}/{key}
|
||||
return `https://${bucket}.${storageDomain}/${imageOrKey}`;
|
||||
}
|
||||
|
||||
if (storageUrl && bucket) {
|
||||
// Path-style: {storageUrl}/{bucket}/{key}
|
||||
return `${storageUrl}/${bucket}/${imageOrKey}`;
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { api } from "~/utils/api";
|
||||
import { DueDateSelector } from "~/views/card/components/DueDateSelector";
|
||||
|
||||
export function CardContextDueDateModal() {
|
||||
const { entityId: cardPublicId, closeModal } = useModal();
|
||||
|
||||
const { data: card, isLoading } = api.card.byId.useQuery(
|
||||
{ cardPublicId: cardPublicId ?? "" },
|
||||
{ enabled: !!cardPublicId && cardPublicId.length >= 12 },
|
||||
);
|
||||
|
||||
if (!cardPublicId) return null;
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
<h2 className="mb-4 text-lg font-semibold text-light-1000 dark:text-dark-1000">
|
||||
{t`Set due date`}
|
||||
</h2>
|
||||
{isLoading ? (
|
||||
<div className="h-10 w-full animate-pulse rounded bg-light-200 dark:bg-dark-300" />
|
||||
) : (
|
||||
<DueDateSelector
|
||||
cardPublicId={cardPublicId}
|
||||
dueDate={card?.dueDate ?? null}
|
||||
/>
|
||||
)}
|
||||
<div className="mt-4 flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
onClick={closeModal}
|
||||
className="rounded-md border border-light-300 bg-light-50 px-3 py-1.5 text-sm font-medium text-light-1000 hover:bg-light-200 dark:border-dark-400 dark:bg-dark-200 dark:text-dark-1000 dark:hover:bg-dark-300"
|
||||
>
|
||||
{t`Done`}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
import {
|
||||
Listbox,
|
||||
ListboxButton,
|
||||
ListboxOption,
|
||||
ListboxOptions,
|
||||
Transition,
|
||||
} from "@headlessui/react";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useState } from "react";
|
||||
import { HiChevronDown } from "react-icons/hi2";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import Input from "~/components/Input";
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { usePopup } from "~/providers/popup";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
interface CardContextDuplicateModalProps {
|
||||
boardPublicId?: string;
|
||||
isTemplate?: boolean;
|
||||
}
|
||||
|
||||
export function CardContextDuplicateModal({
|
||||
boardPublicId: boardPublicIdProp,
|
||||
isTemplate: isTemplateProp,
|
||||
}: CardContextDuplicateModalProps = {}) {
|
||||
const { entityId: cardPublicId, closeModal, getModalState } = useModal();
|
||||
const { showPopup } = usePopup();
|
||||
const utils = api.useUtils();
|
||||
|
||||
const modalState = getModalState("CARD_CONTEXT_DUPLICATE") as
|
||||
| { boardPublicId: string; isTemplate?: boolean }
|
||||
| undefined;
|
||||
const boardPublicId =
|
||||
boardPublicIdProp ?? modalState?.boardPublicId ?? "";
|
||||
const isTemplate = isTemplateProp ?? modalState?.isTemplate ?? false;
|
||||
|
||||
const [listPublicId, setListPublicId] = useState("");
|
||||
const [copyLabels, setCopyLabels] = useState(true);
|
||||
const [copyMembers, setCopyMembers] = useState(true);
|
||||
const [copyChecklists, setCopyChecklists] = useState(true);
|
||||
const [position, setPosition] = useState<string>("");
|
||||
const [title, setTitle] = useState("");
|
||||
|
||||
const { data: card, isLoading: isCardLoading } = api.card.byId.useQuery(
|
||||
{ cardPublicId: cardPublicId ?? "" },
|
||||
{ enabled: !!cardPublicId && cardPublicId.length >= 12 },
|
||||
);
|
||||
|
||||
const boardType = isTemplate ? "template" : "regular";
|
||||
const { data: board } = api.board.byId.useQuery(
|
||||
{ boardPublicId, type: boardType },
|
||||
{ enabled: !!boardPublicId },
|
||||
);
|
||||
const lists = board?.lists ?? [];
|
||||
const listOptions = lists.map((l) => ({ publicId: l.publicId, name: l.name }));
|
||||
const currentListPublicId = card?.list?.publicId;
|
||||
const hasLabels = (card?.labels?.length ?? 0) > 0;
|
||||
const hasMembers = (card?.members?.length ?? 0) > 0;
|
||||
const hasChecklists = (card?.checklists?.length ?? 0) > 0;
|
||||
const hasAnyCopyOption = hasLabels || hasMembers || hasChecklists;
|
||||
|
||||
const duplicateCard = api.card.duplicate.useMutation({
|
||||
onSuccess: () => {
|
||||
showPopup({
|
||||
header: t`Card duplicated`,
|
||||
icon: "success",
|
||||
message: t`The card has been duplicated.`,
|
||||
});
|
||||
closeModal();
|
||||
},
|
||||
onError: () => {
|
||||
showPopup({
|
||||
header: t`Unable to duplicate card`,
|
||||
message: t`Please try again.`,
|
||||
icon: "error",
|
||||
});
|
||||
},
|
||||
onSettled: async () => {
|
||||
await utils.board.byId.invalidate();
|
||||
},
|
||||
});
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (!cardPublicId || !listPublicId) return;
|
||||
const indexNum =
|
||||
position === "" ? undefined : parseInt(position, 10);
|
||||
if (
|
||||
position !== "" &&
|
||||
(indexNum === undefined || isNaN(indexNum) || indexNum < 0)
|
||||
)
|
||||
return;
|
||||
duplicateCard.mutate({
|
||||
cardPublicId,
|
||||
listPublicId,
|
||||
copyLabels,
|
||||
copyMembers,
|
||||
copyChecklists,
|
||||
...(typeof indexNum === "number" && { index: indexNum }),
|
||||
title: title.trim() || undefined,
|
||||
});
|
||||
};
|
||||
|
||||
if (!cardPublicId) return null;
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="p-4">
|
||||
<h2 className="mb-4 text-lg font-semibold text-light-1000 dark:text-dark-1000">
|
||||
{t`Duplicate card`}
|
||||
</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className="mb-1 block text-sm font-medium text-light-900 dark:text-dark-900">
|
||||
{t`List`}
|
||||
</label>
|
||||
<Listbox value={listPublicId} onChange={setListPublicId}>
|
||||
<div className="relative">
|
||||
<ListboxButton
|
||||
className={twMerge(
|
||||
"relative w-full cursor-pointer rounded-md border border-light-300 bg-white py-2 pl-3 pr-10 text-left text-sm shadow-sm focus:outline-none focus:ring-2 focus:ring-light-400 focus:ring-offset-0 dark:border-dark-400 dark:bg-dark-200 dark:text-dark-1000 dark:focus:ring-dark-500",
|
||||
!listPublicId && "text-light-600 dark:text-dark-600",
|
||||
)}
|
||||
>
|
||||
<span className="block truncate">
|
||||
{listPublicId
|
||||
? listOptions.find((o) => o.publicId === listPublicId)
|
||||
?.name
|
||||
: t`Select a list`}
|
||||
</span>
|
||||
<span className="pointer-events-none absolute right-2 top-1/2 flex -translate-y-1/2 items-center">
|
||||
<HiChevronDown
|
||||
className="h-4 w-4 text-light-600 dark:text-dark-600"
|
||||
aria-hidden
|
||||
/>
|
||||
</span>
|
||||
</ListboxButton>
|
||||
<Transition
|
||||
leave="transition ease-in duration-100"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<ListboxOptions className="absolute z-50 mt-1 w-full overflow-hidden rounded-md border border-light-200 bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:border-dark-400 dark:bg-dark-200">
|
||||
<div className="max-h-60 overflow-y-auto py-1 pr-1 scrollbar scrollbar-track-rounded-[4px] scrollbar-thumb-rounded-[4px] scrollbar-w-[8px] scrollbar-track-light-200 scrollbar-thumb-light-400 dark:scrollbar-track-dark-100 dark:scrollbar-thumb-dark-600">
|
||||
{listOptions.map((option) => {
|
||||
const isCurrentList =
|
||||
option.publicId === currentListPublicId;
|
||||
return (
|
||||
<ListboxOption
|
||||
key={option.publicId}
|
||||
value={option.publicId}
|
||||
disabled={isCurrentList}
|
||||
className={({ focus }) =>
|
||||
twMerge(
|
||||
"relative select-none py-2 pl-3 pr-9 text-sm",
|
||||
isCurrentList
|
||||
? "cursor-default opacity-50"
|
||||
: "cursor-pointer",
|
||||
!isCurrentList && focus
|
||||
? "bg-light-200 text-light-1000 dark:bg-dark-400 dark:text-dark-1000"
|
||||
: "text-light-900 dark:text-dark-900",
|
||||
)
|
||||
}
|
||||
>
|
||||
{option.name}
|
||||
</ListboxOption>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</ListboxOptions>
|
||||
</Transition>
|
||||
</div>
|
||||
</Listbox>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="mb-1 block text-sm font-medium text-light-900 dark:text-dark-900">
|
||||
{t`Title (optional)`}
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
value={title}
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
placeholder={card?.title ?? ""}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="mb-1 block text-sm font-medium text-light-900 dark:text-dark-900">
|
||||
{t`Position in list (0 = first, leave empty for end)`}
|
||||
</label>
|
||||
<Input
|
||||
type="number"
|
||||
min={0}
|
||||
value={position}
|
||||
onChange={(e) => setPosition(e.target.value)}
|
||||
placeholder={t`End of list`}
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{hasAnyCopyOption && (
|
||||
<div className="flex flex-col gap-2">
|
||||
{hasLabels && (
|
||||
<div className="flex items-center gap-3">
|
||||
<label className="relative mt-[2px] inline-flex h-[16px] w-[16px] flex-shrink-0 cursor-pointer items-center justify-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={copyLabels}
|
||||
onChange={(e) => setCopyLabels(e.target.checked)}
|
||||
className={twMerge(
|
||||
"h-[16px] w-[16px] appearance-none rounded-md border border-light-500 bg-transparent outline-none ring-0 checked:bg-blue-600 focus:shadow-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none dark:border-dark-500 dark:hover:border-dark-500",
|
||||
"cursor-pointer",
|
||||
)}
|
||||
/>
|
||||
</label>
|
||||
<span className="text-sm text-light-900 dark:text-dark-900">
|
||||
{t`Copy labels`}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{hasMembers && (
|
||||
<div className="flex items-center gap-3">
|
||||
<label className="relative mt-[2px] inline-flex h-[16px] w-[16px] flex-shrink-0 cursor-pointer items-center justify-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={copyMembers}
|
||||
onChange={(e) => setCopyMembers(e.target.checked)}
|
||||
className={twMerge(
|
||||
"h-[16px] w-[16px] appearance-none rounded-md border border-light-500 bg-transparent outline-none ring-0 checked:bg-blue-600 focus:shadow-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none dark:border-dark-500 dark:hover:border-dark-500",
|
||||
"cursor-pointer",
|
||||
)}
|
||||
/>
|
||||
</label>
|
||||
<span className="text-sm text-light-900 dark:text-dark-900">
|
||||
{t`Copy members`}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{hasChecklists && (
|
||||
<div className="flex items-center gap-3">
|
||||
<label className="relative mt-[2px] inline-flex h-[16px] w-[16px] flex-shrink-0 cursor-pointer items-center justify-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={copyChecklists}
|
||||
onChange={(e) => setCopyChecklists(e.target.checked)}
|
||||
className={twMerge(
|
||||
"h-[16px] w-[16px] appearance-none rounded-md border border-light-500 bg-transparent outline-none ring-0 checked:bg-blue-600 focus:shadow-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none dark:border-dark-500 dark:hover:border-dark-500",
|
||||
"cursor-pointer",
|
||||
)}
|
||||
/>
|
||||
</label>
|
||||
<span className="text-sm text-light-900 dark:text-dark-900">
|
||||
{t`Copy checklists`}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex justify-end gap-2">
|
||||
<Button type="button" variant="secondary" onClick={closeModal}>
|
||||
{t`Cancel`}
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
disabled={
|
||||
!listPublicId ||
|
||||
duplicateCard.isPending ||
|
||||
isCardLoading ||
|
||||
lists.length === 0
|
||||
}
|
||||
>
|
||||
{duplicateCard.isPending ? t`Duplicating…` : t`Duplicate`}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { api } from "~/utils/api";
|
||||
import LabelIcon from "~/components/LabelIcon";
|
||||
import LabelSelector from "~/views/card/components/LabelSelector";
|
||||
|
||||
export function CardContextLabelsModal() {
|
||||
const { entityId: cardPublicId, closeModal } = useModal();
|
||||
|
||||
const { data: card, isLoading } = api.card.byId.useQuery(
|
||||
{ cardPublicId: cardPublicId ?? "" },
|
||||
{ enabled: !!cardPublicId && cardPublicId.length >= 12 },
|
||||
);
|
||||
|
||||
const boardLabels = card?.list?.board?.labels ?? [];
|
||||
const selectedLabels = card?.labels ?? [];
|
||||
|
||||
const formattedLabels = boardLabels.map((label) => ({
|
||||
key: label.publicId,
|
||||
value: label.name,
|
||||
selected: selectedLabels.some((l) => l.publicId === label.publicId),
|
||||
leftIcon: <LabelIcon colourCode={label.colourCode} />,
|
||||
}));
|
||||
|
||||
if (!cardPublicId) return null;
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
<h2 className="mb-4 text-lg font-semibold text-light-1000 dark:text-dark-1000">
|
||||
{t`Labels`}
|
||||
</h2>
|
||||
{isLoading ? (
|
||||
<div className="h-10 w-full animate-pulse rounded bg-light-200 dark:bg-dark-300" />
|
||||
) : (
|
||||
<LabelSelector
|
||||
cardPublicId={cardPublicId}
|
||||
labels={formattedLabels}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
)}
|
||||
<div className="mt-4 flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
onClick={closeModal}
|
||||
className="rounded-md border border-light-300 bg-light-50 px-3 py-1.5 text-sm font-medium text-light-1000 hover:bg-light-200 dark:border-dark-400 dark:bg-dark-200 dark:text-dark-1000 dark:hover:bg-dark-300"
|
||||
>
|
||||
{t`Done`}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { api } from "~/utils/api";
|
||||
import { formatMemberDisplayName, getAvatarUrl } from "~/utils/helpers";
|
||||
import Avatar from "~/components/Avatar";
|
||||
import MemberSelector from "~/views/card/components/MemberSelector";
|
||||
|
||||
export function CardContextMembersModal() {
|
||||
const { entityId: cardPublicId, closeModal } = useModal();
|
||||
|
||||
const { data: card, isLoading } = api.card.byId.useQuery(
|
||||
{ cardPublicId: cardPublicId ?? "" },
|
||||
{ enabled: !!cardPublicId && cardPublicId.length >= 12 },
|
||||
);
|
||||
|
||||
const board = card?.list?.board;
|
||||
const workspaceMembers = board?.workspace?.members ?? [];
|
||||
const selectedMembers = card?.members ?? [];
|
||||
|
||||
const formattedMembers = workspaceMembers.map((member) => {
|
||||
const isSelected = selectedMembers.some(
|
||||
(m) => m.publicId === member.publicId,
|
||||
);
|
||||
return {
|
||||
key: member.publicId,
|
||||
value: formatMemberDisplayName(
|
||||
member.user?.name ?? null,
|
||||
member.user?.email ?? member.email,
|
||||
),
|
||||
imageUrl: member.user?.image ? getAvatarUrl(member.user.image) : undefined,
|
||||
selected: isSelected,
|
||||
leftIcon: (
|
||||
<Avatar
|
||||
size="xs"
|
||||
name={member.user?.name ?? ""}
|
||||
imageUrl={
|
||||
member.user?.image ? getAvatarUrl(member.user.image) : undefined
|
||||
}
|
||||
email={member.user?.email ?? member.email}
|
||||
/>
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
if (!cardPublicId) return null;
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
<h2 className="mb-4 text-lg font-semibold text-light-1000 dark:text-dark-1000">
|
||||
{t`Manage members`}
|
||||
</h2>
|
||||
{isLoading ? (
|
||||
<div className="h-10 w-full animate-pulse rounded bg-light-200 dark:bg-dark-300" />
|
||||
) : (
|
||||
<MemberSelector
|
||||
cardPublicId={cardPublicId}
|
||||
members={formattedMembers}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
)}
|
||||
<div className="mt-4 flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
onClick={closeModal}
|
||||
className="rounded-md border border-light-300 bg-light-50 px-3 py-1.5 text-sm font-medium text-light-1000 hover:bg-light-200 dark:border-dark-400 dark:bg-dark-200 dark:text-dark-1000 dark:hover:bg-dark-300"
|
||||
>
|
||||
{t`Done`}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
130
apps/web/src/views/board/components/CardContextMenu.tsx
Normal file
130
apps/web/src/views/board/components/CardContextMenu.tsx
Normal file
@@ -0,0 +1,130 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useEffect, useRef } from "react";
|
||||
import {
|
||||
HiLink,
|
||||
HiOutlineCalendar,
|
||||
HiOutlineDocumentDuplicate,
|
||||
HiOutlineTag,
|
||||
HiOutlineTrash,
|
||||
HiOutlineUserGroup,
|
||||
HiOutlineArrowRightCircle,
|
||||
} from "react-icons/hi2";
|
||||
|
||||
export type CardContextMenuAction =
|
||||
| "members"
|
||||
| "move"
|
||||
| "labels"
|
||||
| "dueDate"
|
||||
| "copyLink"
|
||||
| "duplicate"
|
||||
| "delete";
|
||||
|
||||
interface CardContextMenuProps {
|
||||
x: number;
|
||||
y: number;
|
||||
onClose: () => void;
|
||||
onAction: (action: CardContextMenuAction) => void;
|
||||
canEdit: boolean;
|
||||
}
|
||||
|
||||
const MENU_ITEMS: {
|
||||
action: CardContextMenuAction;
|
||||
label: string;
|
||||
icon: React.ReactNode;
|
||||
requiresEdit: boolean;
|
||||
}[] = [
|
||||
{
|
||||
action: "members",
|
||||
label: t`Manage members`,
|
||||
icon: <HiOutlineUserGroup className="h-4 w-4 shrink-0" />,
|
||||
requiresEdit: true,
|
||||
},
|
||||
{
|
||||
action: "move",
|
||||
label: t`Move to another list`,
|
||||
icon: <HiOutlineArrowRightCircle className="h-4 w-4 shrink-0" />,
|
||||
requiresEdit: true,
|
||||
},
|
||||
{
|
||||
action: "labels",
|
||||
label: t`Add / edit label`,
|
||||
icon: <HiOutlineTag className="h-4 w-4 shrink-0" />,
|
||||
requiresEdit: true,
|
||||
},
|
||||
{
|
||||
action: "dueDate",
|
||||
label: t`Set due date`,
|
||||
icon: <HiOutlineCalendar className="h-4 w-4 shrink-0" />,
|
||||
requiresEdit: true,
|
||||
},
|
||||
{
|
||||
action: "copyLink",
|
||||
label: t`Copy link to card`,
|
||||
icon: <HiLink className="h-4 w-4 shrink-0" />,
|
||||
requiresEdit: false,
|
||||
},
|
||||
{
|
||||
action: "duplicate",
|
||||
label: t`Duplicate card`,
|
||||
icon: <HiOutlineDocumentDuplicate className="h-4 w-4 shrink-0" />,
|
||||
requiresEdit: true,
|
||||
},
|
||||
{
|
||||
action: "delete",
|
||||
label: t`Delete card`,
|
||||
icon: <HiOutlineTrash className="h-4 w-4 shrink-0" />,
|
||||
requiresEdit: true,
|
||||
},
|
||||
];
|
||||
|
||||
export function CardContextMenu({
|
||||
x,
|
||||
y,
|
||||
onClose,
|
||||
onAction,
|
||||
canEdit,
|
||||
}: CardContextMenuProps) {
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (e: MouseEvent) => {
|
||||
if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
const handleEscape = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") onClose();
|
||||
};
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
document.addEventListener("keydown", handleEscape);
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", handleClickOutside);
|
||||
document.removeEventListener("keydown", handleEscape);
|
||||
};
|
||||
}, [onClose]);
|
||||
|
||||
const items = MENU_ITEMS.filter((item) => !item.requiresEdit || canEdit);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={menuRef}
|
||||
className="fixed z-[200] min-w-[200px] rounded-md border border-light-200 bg-white py-1 shadow-lg dark:border-dark-400 dark:bg-dark-200"
|
||||
style={{ left: x, top: y }}
|
||||
>
|
||||
{items.map(({ action, label, icon }) => (
|
||||
<button
|
||||
key={action}
|
||||
type="button"
|
||||
onClick={() => {
|
||||
onAction(action);
|
||||
onClose();
|
||||
}}
|
||||
className="flex w-full items-center gap-2 px-3 py-2 text-left text-sm text-neutral-900 hover:bg-light-200 dark:text-dark-1000 dark:hover:bg-dark-400"
|
||||
>
|
||||
{icon}
|
||||
{label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
101
apps/web/src/views/board/components/CardContextMoveListModal.tsx
Normal file
101
apps/web/src/views/board/components/CardContextMoveListModal.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { usePopup } from "~/providers/popup";
|
||||
import { api } from "~/utils/api";
|
||||
import { invalidateCard } from "~/utils/cardInvalidation";
|
||||
|
||||
export function CardContextMoveListModal() {
|
||||
const { entityId: cardPublicId, closeModal } = useModal();
|
||||
const { showPopup } = usePopup();
|
||||
const utils = api.useUtils();
|
||||
|
||||
const { data: card, isLoading } = api.card.byId.useQuery(
|
||||
{ cardPublicId: cardPublicId ?? "" },
|
||||
{ enabled: !!cardPublicId && cardPublicId.length >= 12 },
|
||||
);
|
||||
|
||||
const updateCardList = api.card.update.useMutation({
|
||||
onMutate: async (vars) => {
|
||||
if (!cardPublicId) return undefined;
|
||||
await utils.card.byId.cancel();
|
||||
const previous = utils.card.byId.getData({ cardPublicId });
|
||||
utils.card.byId.setData({ cardPublicId }, (old) => {
|
||||
if (!old) return old;
|
||||
const list = old.list.board?.lists?.find(
|
||||
(l) => l.publicId === vars.listPublicId,
|
||||
);
|
||||
if (!list) return old;
|
||||
return {
|
||||
...old,
|
||||
list: { ...old.list, publicId: list.publicId, name: list.name },
|
||||
};
|
||||
});
|
||||
return { previous };
|
||||
},
|
||||
onError: (_err, _vars, ctx) => {
|
||||
if (cardPublicId && ctx?.previous) {
|
||||
utils.card.byId.setData({ cardPublicId }, ctx.previous);
|
||||
}
|
||||
showPopup({
|
||||
header: t`Unable to move card`,
|
||||
message: t`Please try again.`,
|
||||
icon: "error",
|
||||
});
|
||||
},
|
||||
onSettled: async () => {
|
||||
if (cardPublicId) {
|
||||
await invalidateCard(utils, cardPublicId);
|
||||
await utils.board.byId.invalidate();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const lists = card?.list?.board?.lists ?? [];
|
||||
const currentListPublicId = card?.list?.publicId;
|
||||
|
||||
const handleSelectList = (listPublicId: string) => {
|
||||
if (listPublicId === currentListPublicId || !cardPublicId) return;
|
||||
updateCardList.mutate(
|
||||
{ cardPublicId, listPublicId, index: 0 },
|
||||
{ onSuccess: closeModal },
|
||||
);
|
||||
};
|
||||
|
||||
if (!cardPublicId) return null;
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
<h2 className="mb-4 text-lg font-semibold text-light-1000 dark:text-dark-1000">
|
||||
{t`Move to list`}
|
||||
</h2>
|
||||
{isLoading ? (
|
||||
<div className="space-y-2">
|
||||
{[1, 2, 3].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="h-10 w-full animate-pulse rounded bg-light-200 dark:bg-dark-300"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="max-h-[60vh] overflow-y-auto pr-1 scrollbar scrollbar-track-rounded-[4px] scrollbar-thumb-rounded-[4px] scrollbar-w-[8px] scrollbar-track-light-200 scrollbar-thumb-light-400 dark:scrollbar-track-dark-100 dark:scrollbar-thumb-dark-600">
|
||||
<ul className="space-y-1">
|
||||
{lists.map((list) => (
|
||||
<li key={list.publicId}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleSelectList(list.publicId)}
|
||||
disabled={list.publicId === currentListPublicId}
|
||||
className="w-full rounded-md px-3 py-2 text-left text-sm hover:bg-light-200 disabled:opacity-50 dark:hover:bg-dark-400"
|
||||
>
|
||||
{list.name}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -515,7 +515,7 @@ export function NewCardForm({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-5 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<div className="mt-5 flex items-center justify-end space-x-4 border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<Toggle
|
||||
label={t`Create another`}
|
||||
isChecked={isCreateAnotherEnabled}
|
||||
|
||||
@@ -136,7 +136,7 @@ export function NewListForm({
|
||||
}}
|
||||
/>
|
||||
</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">
|
||||
<div className="mt-12 flex items-center justify-end space-x-4 border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<Toggle
|
||||
label={t`Create another`}
|
||||
isChecked={isCreateAnotherEnabled}
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { DropResult } from "react-beautiful-dnd";
|
||||
import Link from "next/link";
|
||||
import { useParams } from "next/navigation";
|
||||
import { useRouter } from "next/router";
|
||||
import { env } from "next-runtime-env";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { keepPreviousData } from "@tanstack/react-query";
|
||||
import { useEffect, useState } from "react";
|
||||
@@ -15,6 +16,7 @@ import {
|
||||
|
||||
import type { UpdateBoardInput } from "@kan/api/types";
|
||||
|
||||
import type { CardContextMenuAction } from "./components/CardContextMenu";
|
||||
import Button from "~/components/Button";
|
||||
import { DeleteLabelConfirmation } from "~/components/DeleteLabelConfirmation";
|
||||
import { LabelForm } from "~/components/LabelForm";
|
||||
@@ -26,16 +28,23 @@ import { StrictModeDroppable as Droppable } from "~/components/StrictModeDroppab
|
||||
import { Tooltip } from "~/components/Tooltip";
|
||||
import { EditYouTubeModal } from "~/components/YouTubeEmbed/EditYouTubeModal";
|
||||
import { useDragToScroll } from "~/hooks/useDragToScroll";
|
||||
import { useScrollRestore } from "~/hooks/useScrollRestore";
|
||||
import { usePermissions } from "~/hooks/usePermissions";
|
||||
import { useScrollRestore } from "~/hooks/useScrollRestore";
|
||||
import { useKeyboardShortcut } from "~/providers/keyboard-shortcuts";
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { usePopup } from "~/providers/popup";
|
||||
import { useWorkspace } from "~/providers/workspace";
|
||||
import { api } from "~/utils/api";
|
||||
import { formatToArray } from "~/utils/helpers";
|
||||
import { DeleteCardConfirmation } from "~/views/card/components/DeleteCardConfirmation";
|
||||
import BoardDropdown from "./components/BoardDropdown";
|
||||
import Card from "./components/Card";
|
||||
import { CardContextDueDateModal } from "./components/CardContextDueDateModal";
|
||||
import { CardContextDuplicateModal } from "./components/CardContextDuplicateModal";
|
||||
import { CardContextLabelsModal } from "./components/CardContextLabelsModal";
|
||||
import { CardContextMembersModal } from "./components/CardContextMembersModal";
|
||||
import { CardContextMenu } from "./components/CardContextMenu";
|
||||
import { CardContextMoveListModal } from "./components/CardContextMoveListModal";
|
||||
import { DeleteBoardConfirmation } from "./components/DeleteBoardConfirmation";
|
||||
import { DeleteListConfirmation } from "./components/DeleteListConfirmation";
|
||||
import Filters from "./components/Filters";
|
||||
@@ -55,11 +64,18 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
const utils = api.useUtils();
|
||||
const { showPopup } = usePopup();
|
||||
const { workspace } = useWorkspace();
|
||||
const { openModal, modalContentType, entityId, isOpen } = useModal();
|
||||
const { openModal, modalContentType, entityId, isOpen, setModalState } =
|
||||
useModal();
|
||||
const [selectedPublicListId, setSelectedPublicListId] =
|
||||
useState<PublicListId>("");
|
||||
const [isInitialLoading, setIsInitialLoading] = useState(true);
|
||||
|
||||
const [contextMenu, setContextMenu] = useState<{
|
||||
x: number;
|
||||
y: number;
|
||||
cardPublicId: string;
|
||||
} | null>(null);
|
||||
|
||||
const { ref: scrollRef, onMouseDown } = useDragToScroll({
|
||||
enabled: true,
|
||||
direction: "horizontal",
|
||||
@@ -134,7 +150,10 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
// Redirect to 404 if board doesn't exist
|
||||
useEffect(() => {
|
||||
if (router.isReady && boardId && !isQueryLoading) {
|
||||
if (error?.data?.code === "NOT_FOUND" || (!boardData && !isQueryLoading)) {
|
||||
if (
|
||||
error?.data?.code === "NOT_FOUND" ||
|
||||
(!boardData && !isQueryLoading)
|
||||
) {
|
||||
router.replace("/404");
|
||||
}
|
||||
}
|
||||
@@ -152,7 +171,12 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
|
||||
const isLoading = isInitialLoading || isQueryLoading;
|
||||
|
||||
useScrollRestore(boardId, scrollRef, router, !isLoading && (boardData?.lists.length ?? 0) > 0);
|
||||
useScrollRestore(
|
||||
boardId,
|
||||
scrollRef,
|
||||
router,
|
||||
!isLoading && (boardData?.lists.length ?? 0) > 0,
|
||||
);
|
||||
|
||||
const updateListMutation = api.list.update.useMutation({
|
||||
onMutate: async (args) => {
|
||||
@@ -267,6 +291,56 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
setSelectedPublicListId(publicBoardId);
|
||||
};
|
||||
|
||||
const handleCardContextMenuAction = (action: CardContextMenuAction) => {
|
||||
const cardPublicId = contextMenu?.cardPublicId;
|
||||
if (!cardPublicId) return;
|
||||
setContextMenu(null);
|
||||
if (action === "copyLink") {
|
||||
const path = isTemplate
|
||||
? `/templates/${boardId}/cards/${cardPublicId}`
|
||||
: `/cards/${cardPublicId}`;
|
||||
const url = `${typeof window !== "undefined" ? window.location.origin : ""}${path}`;
|
||||
void navigator.clipboard.writeText(url).then(
|
||||
() => {
|
||||
showPopup({
|
||||
header: t`Link copied`,
|
||||
icon: "success",
|
||||
message: t`Card URL copied to clipboard`,
|
||||
});
|
||||
},
|
||||
() => {
|
||||
showPopup({
|
||||
header: t`Unable to copy link`,
|
||||
icon: "error",
|
||||
message: t`Please try again.`,
|
||||
});
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (action === "duplicate") {
|
||||
setModalState("CARD_CONTEXT_DUPLICATE", {
|
||||
boardPublicId: boardId ?? "",
|
||||
isTemplate: !!isTemplate,
|
||||
});
|
||||
openModal("CARD_CONTEXT_DUPLICATE", cardPublicId);
|
||||
return;
|
||||
}
|
||||
if (action === "delete") {
|
||||
openModal("DELETE_CARD", cardPublicId);
|
||||
return;
|
||||
}
|
||||
const modalType =
|
||||
action === "members"
|
||||
? "CARD_CONTEXT_MEMBERS"
|
||||
: action === "move"
|
||||
? "CARD_CONTEXT_MOVE_LIST"
|
||||
: action === "labels"
|
||||
? "CARD_CONTEXT_LABELS"
|
||||
: "CARD_CONTEXT_DUE_DATE";
|
||||
openModal(modalType, cardPublicId);
|
||||
};
|
||||
|
||||
const onDragEnd = ({
|
||||
source: _source,
|
||||
destination,
|
||||
@@ -403,6 +477,49 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
>
|
||||
<EditYouTubeModal />
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
modalSize="sm"
|
||||
isVisible={isOpen && modalContentType === "CARD_CONTEXT_MEMBERS"}
|
||||
>
|
||||
<CardContextMembersModal />
|
||||
</Modal>
|
||||
<Modal
|
||||
modalSize="sm"
|
||||
isVisible={isOpen && modalContentType === "CARD_CONTEXT_MOVE_LIST"}
|
||||
>
|
||||
<CardContextMoveListModal />
|
||||
</Modal>
|
||||
<Modal
|
||||
modalSize="sm"
|
||||
isVisible={isOpen && modalContentType === "CARD_CONTEXT_LABELS"}
|
||||
>
|
||||
<CardContextLabelsModal />
|
||||
</Modal>
|
||||
<Modal
|
||||
modalSize="sm"
|
||||
isVisible={isOpen && modalContentType === "CARD_CONTEXT_DUE_DATE"}
|
||||
>
|
||||
<CardContextDueDateModal />
|
||||
</Modal>
|
||||
<Modal
|
||||
modalSize="md"
|
||||
isVisible={isOpen && modalContentType === "CARD_CONTEXT_DUPLICATE"}
|
||||
>
|
||||
<CardContextDuplicateModal
|
||||
boardPublicId={boardId ?? ""}
|
||||
isTemplate={!!isTemplate}
|
||||
/>
|
||||
</Modal>
|
||||
<Modal
|
||||
modalSize="sm"
|
||||
isVisible={isOpen && modalContentType === "DELETE_CARD"}
|
||||
>
|
||||
<DeleteCardConfirmation
|
||||
cardPublicId={entityId}
|
||||
boardPublicId={boardId ?? ""}
|
||||
/>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -605,18 +722,35 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
)
|
||||
e.preventDefault();
|
||||
}}
|
||||
onContextMenu={(e) => {
|
||||
if (
|
||||
card.publicId.startsWith(
|
||||
"PLACEHOLDER",
|
||||
) ||
|
||||
env("NEXT_PUBLIC_KAN_ENV") ===
|
||||
"cloud"
|
||||
)
|
||||
return;
|
||||
e.preventDefault();
|
||||
setContextMenu({
|
||||
x: e.clientX,
|
||||
y: e.clientY,
|
||||
cardPublicId: card.publicId,
|
||||
});
|
||||
}}
|
||||
key={card.publicId}
|
||||
href={
|
||||
isTemplate
|
||||
? `/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}
|
||||
@@ -653,6 +787,15 @@ export default function BoardPage({ isTemplate }: { isTemplate?: boolean }) {
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
{contextMenu && (
|
||||
<CardContextMenu
|
||||
x={contextMenu.x}
|
||||
y={contextMenu.y}
|
||||
onClose={() => setContextMenu(null)}
|
||||
onAction={handleCardContextMenuAction}
|
||||
canEdit={!!canEditCard}
|
||||
/>
|
||||
)}
|
||||
{renderModalContent()}
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -184,7 +184,7 @@ const SelectSource = ({
|
||||
/>
|
||||
</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">
|
||||
<div className="mt-12 flex items-center justify-end space-x-4 border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<div>
|
||||
<Button
|
||||
type="submit"
|
||||
@@ -310,7 +310,7 @@ const ImportGithub: React.FC = () => {
|
||||
<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">
|
||||
<div className="mt-12 flex items-center justify-end space-x-4 border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<Toggle
|
||||
label={t`Select all`}
|
||||
isChecked={!!isSelectAllEnabled}
|
||||
@@ -459,7 +459,7 @@ const ImportTrello: React.FC = () => {
|
||||
<form onSubmit={handleSubmitBoards(onSubmitBoards)}>
|
||||
<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">
|
||||
<div className="mt-12 flex items-center justify-end space-x-4 border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<Toggle
|
||||
label={t`Select all`}
|
||||
isChecked={!!isSelectAllEnabled}
|
||||
|
||||
@@ -148,7 +148,7 @@ export function NewBoardForm({ isTemplate }: { isTemplate?: boolean }) {
|
||||
showTemplates={showTemplates}
|
||||
customTemplates={formattedTemplates ?? []}
|
||||
/>
|
||||
<div className="mt-12 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<div className="mt-12 flex items-center justify-end space-x-4 border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
{!isTemplate && (
|
||||
<Toggle
|
||||
label={t`Use template`}
|
||||
|
||||
@@ -78,6 +78,7 @@ export default function LabelSelector({
|
||||
},
|
||||
onSettled: async () => {
|
||||
await invalidateCard(utils, cardPublicId);
|
||||
await utils.board.byId.invalidate();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ export default function ListSelector({
|
||||
},
|
||||
onSettled: async () => {
|
||||
await invalidateCard(utils, cardPublicId);
|
||||
await utils.board.byId.invalidate();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ export default function MemberSelector({
|
||||
},
|
||||
onSettled: async () => {
|
||||
await invalidateCard(utils, cardPublicId);
|
||||
await utils.board.byId.invalidate();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -341,7 +341,7 @@ export function InviteMemberForm({
|
||||
)}
|
||||
</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">
|
||||
<div className="mt-12 flex items-center justify-end space-x-4 border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<Toggle
|
||||
label={
|
||||
isShareInviteLinkEnabled
|
||||
|
||||
289
apps/web/src/views/onboarding/select-plan/index.tsx
Normal file
289
apps/web/src/views/onboarding/select-plan/index.tsx
Normal file
@@ -0,0 +1,289 @@
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { Radio, RadioGroup } from "@headlessui/react";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
import { HiUser } from "react-icons/hi2";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { authClient } from "@kan/auth/client";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
type PlanId = "solo" | "team" | "pro";
|
||||
type Billing = "monthly" | "annual";
|
||||
|
||||
// Each user orbits via a zero-size pivot div at center (144,144) that rotates.
|
||||
// The icon is offset from the pivot by `radius` pixels along the x-axis.
|
||||
// A counter-rotation on the icon keeps it upright.
|
||||
const ORBIT_USERS: Record<
|
||||
PlanId,
|
||||
{ id: string; angle: number; radius: number; duration: number }[]
|
||||
> = {
|
||||
solo: [],
|
||||
team: [
|
||||
{ id: "t1", angle: 45, radius: 104, duration: 50 },
|
||||
{ id: "t2", angle: 170, radius: 104, duration: 50 },
|
||||
{ id: "t3", angle: 290, radius: 104, duration: 50 },
|
||||
],
|
||||
pro: [
|
||||
{ id: "t1", angle: 45, radius: 104, duration: 50 },
|
||||
{ id: "t2", angle: 170, radius: 104, duration: 50 },
|
||||
{ id: "t3", angle: 290, radius: 104, duration: 50 },
|
||||
{ id: "p1", angle: 10, radius: 144, duration: 70 },
|
||||
{ id: "p2", angle: 120, radius: 144, duration: 70 },
|
||||
{ id: "p4", angle: 240, radius: 144, duration: 70 },
|
||||
{ id: "p3", angle: 230, radius: 64, duration: 30 },
|
||||
],
|
||||
};
|
||||
|
||||
export default function SelectPlanView() {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const [selected, setSelected] = useState<PlanId>(
|
||||
(searchParams.get("plan") as PlanId | null) ?? "solo",
|
||||
);
|
||||
const [billing, setBilling] = useState<Billing>(
|
||||
(searchParams.get("billing") as Billing | null) ?? "annual",
|
||||
);
|
||||
const returnUrl = searchParams.get("returnUrl") ?? "/boards";
|
||||
const { data: workspaces } = api.workspace.all.useQuery();
|
||||
const { data: session } = authClient.useSession();
|
||||
const { data: user } = api.user.getUser.useQuery(undefined, {
|
||||
enabled: !!session?.user,
|
||||
});
|
||||
|
||||
const userImage = user?.image ?? session?.user.image ?? null;
|
||||
|
||||
const hasExistingWorkspace = !!workspaces?.length;
|
||||
|
||||
const FREQUENCIES: { value: Billing; label: string }[] = [
|
||||
{ value: "monthly", label: t`Monthly` },
|
||||
{ value: "annual", label: t`Annual` },
|
||||
];
|
||||
|
||||
const PLANS: {
|
||||
id: PlanId;
|
||||
name: string;
|
||||
monthly: string;
|
||||
annual: string;
|
||||
description: string;
|
||||
trial?: boolean;
|
||||
}[] = [
|
||||
{
|
||||
id: "solo",
|
||||
name: t`Solo`,
|
||||
monthly: t`Free`,
|
||||
annual: t`Free`,
|
||||
description: t`Good for individuals starting out who just need the essentials.`,
|
||||
},
|
||||
{
|
||||
id: "team",
|
||||
name: t`Team`,
|
||||
monthly: "$10/user/mo",
|
||||
annual: "$8/user/mo",
|
||||
description: t`Best for small teams who want to collaborate and move faster together.`,
|
||||
trial: true,
|
||||
},
|
||||
{
|
||||
id: "pro",
|
||||
name: t`Pro`,
|
||||
monthly: "$29/mo",
|
||||
annual: "$23/mo",
|
||||
description: t`Unlimited members and a custom workspace username for teams ready to scale.`,
|
||||
trial: true,
|
||||
},
|
||||
];
|
||||
|
||||
const handleSelectPlan = (plan: PlanId) => {
|
||||
setSelected(plan);
|
||||
router.replace(`/onboarding/select-plan?plan=${plan}&billing=${billing}&returnUrl=${encodeURIComponent(returnUrl)}`);
|
||||
};
|
||||
|
||||
const handleSetBilling = (b: Billing) => {
|
||||
setBilling(b);
|
||||
router.replace(`/onboarding/select-plan?plan=${selected}&billing=${b}&returnUrl=${encodeURIComponent(returnUrl)}`);
|
||||
};
|
||||
|
||||
const handleContinue = () =>
|
||||
router.push(`/onboarding/workspace?plan=${selected}&billing=${billing}&returnUrl=${encodeURIComponent(returnUrl)}`);
|
||||
|
||||
const handleCancel = () => router.push(returnUrl);
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col items-center justify-center gap-4 bg-light-100 px-4 py-8 dark:bg-dark-50 md:px-6">
|
||||
<div className="w-full max-w-3xl overflow-hidden rounded-xl border border-light-400 bg-light-200 shadow-xl dark:border-dark-400 dark:bg-dark-100">
|
||||
<div className="flex flex-col md:h-[520px] md:flex-row">
|
||||
{/* Left panel */}
|
||||
<div className="flex flex-col p-6 md:w-[55%] md:p-8">
|
||||
<div className="flex-1">
|
||||
<h2 className="text-xl font-bold text-light-1000 dark:text-dark-1000">
|
||||
{t`Choose a plan`}
|
||||
</h2>
|
||||
<p className="mt-1 text-sm text-light-800 dark:text-dark-800">
|
||||
{t`Pick a plan to get started. All paid plans include a 14-day free trial.`}
|
||||
</p>
|
||||
|
||||
{/* Billing toggle */}
|
||||
<div className="mt-4 flex justify-end">
|
||||
<RadioGroup
|
||||
value={billing}
|
||||
onChange={handleSetBilling}
|
||||
className="grid grid-cols-2 gap-x-1 rounded-full p-1 text-center text-xs font-semibold ring-1 ring-inset ring-light-600 dark:ring-dark-600"
|
||||
>
|
||||
{FREQUENCIES.map((f) => (
|
||||
<Radio
|
||||
key={f.value}
|
||||
value={f.value}
|
||||
className={twMerge(
|
||||
"cursor-pointer rounded-full px-2.5 py-0.5 text-xs transition-colors",
|
||||
billing === f.value
|
||||
? "bg-dark-50 text-white dark:bg-light-50 dark:text-dark-50"
|
||||
: "text-light-900 hover:bg-light-200 dark:text-dark-900 dark:hover:bg-dark-200",
|
||||
)}
|
||||
>
|
||||
{f.label}
|
||||
</Radio>
|
||||
))}
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 space-y-3">
|
||||
{PLANS.map((plan) => {
|
||||
const badge =
|
||||
billing === "annual" ? plan.annual : plan.monthly;
|
||||
return (
|
||||
<button
|
||||
key={plan.id}
|
||||
type="button"
|
||||
onClick={() => handleSelectPlan(plan.id)}
|
||||
className={`relative w-full rounded-lg border px-4 py-3 text-left transition-colors ${
|
||||
selected === plan.id
|
||||
? "border-light-700 bg-light-300 dark:border-dark-600 dark:bg-dark-200"
|
||||
: "border-light-500 bg-light-200 hover:border-light-600 dark:border-dark-500 dark:bg-dark-100 dark:hover:border-dark-600"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex-1 pr-8">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm font-semibold text-light-1000 dark:text-dark-1000">
|
||||
{plan.name}
|
||||
</span>
|
||||
<span className="rounded-full bg-neutral-700 px-2 py-px text-[11px] font-medium text-neutral-200">
|
||||
{badge}
|
||||
</span>
|
||||
{plan.trial && billing === "annual" && (
|
||||
<span className="rounded-full bg-emerald-500/10 px-2 py-px text-[11px] font-medium text-emerald-600 ring-1 ring-inset ring-emerald-500/20 dark:text-emerald-400">
|
||||
-20%
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="mt-1 text-xs text-light-800 dark:text-dark-800">
|
||||
{plan.description}
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-0.5 flex-shrink-0">
|
||||
<div
|
||||
className={`flex h-4 w-4 items-center justify-center rounded-full border-2 ${
|
||||
selected === plan.id
|
||||
? "border-light-900 bg-light-900 dark:border-dark-900 dark:bg-dark-900"
|
||||
: "border-light-700 dark:border-dark-700"
|
||||
}`}
|
||||
>
|
||||
{selected === plan.id && (
|
||||
<div className="h-1.5 w-1.5 rounded-full bg-light-100 dark:bg-dark-100" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex justify-end gap-2 md:mt-8">
|
||||
{hasExistingWorkspace && (
|
||||
<Button variant="ghost" onClick={handleCancel}>
|
||||
{t`Cancel`}
|
||||
</Button>
|
||||
)}
|
||||
<Button onClick={handleContinue}>{t`Continue`}</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right panel */}
|
||||
<div className="hidden items-center justify-center bg-light-200 dark:bg-dark-200 md:flex md:w-[45%]">
|
||||
<div className="relative h-72 w-72">
|
||||
{/* Orbit rings */}
|
||||
<div className="absolute inset-0 m-auto h-72 w-72 rounded-full border border-light-400 dark:border-dark-400" />
|
||||
<div className="absolute inset-0 m-auto h-52 w-52 rounded-full border border-light-400 dark:border-dark-400" />
|
||||
<div className="absolute inset-0 m-auto h-32 w-32 rounded-full border border-light-400 dark:border-dark-400" />
|
||||
|
||||
{/* Centre person */}
|
||||
<div className="absolute inset-0 m-auto flex h-16 w-16 items-center justify-center overflow-hidden rounded-full bg-light-300 dark:bg-dark-300">
|
||||
{userImage ? (
|
||||
<img
|
||||
src={userImage}
|
||||
alt={t`Your avatar`}
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<HiUser className="h-7 w-7 text-light-700 dark:text-dark-700" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Orbiting users — zero-size pivot at center rotates; icon offset by radius stays on the ring */}
|
||||
<AnimatePresence>
|
||||
{ORBIT_USERS[selected].map((u) => (
|
||||
<motion.div
|
||||
key={u.id}
|
||||
style={{ position: "absolute", left: 144, top: 144 }}
|
||||
initial={{ opacity: 0, rotate: u.angle }}
|
||||
animate={{ opacity: 1, rotate: u.angle + 360 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{
|
||||
opacity: { duration: 0.3 },
|
||||
rotate: {
|
||||
duration: u.duration,
|
||||
repeat: Infinity,
|
||||
ease: "linear",
|
||||
repeatType: "loop",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{/* Counter-rotate icon so it stays upright */}
|
||||
<motion.div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: u.radius - 12,
|
||||
top: -12,
|
||||
}}
|
||||
initial={{ rotate: -u.angle }}
|
||||
animate={{ rotate: -(u.angle + 360) }}
|
||||
transition={{
|
||||
duration: u.duration,
|
||||
repeat: Infinity,
|
||||
ease: "linear",
|
||||
repeatType: "loop",
|
||||
}}
|
||||
className="flex h-6 w-6 items-center justify-center rounded-full bg-light-400 dark:bg-dark-400"
|
||||
>
|
||||
<HiUser className="h-3.5 w-3.5 text-light-800 dark:text-dark-800" />
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{!hasExistingWorkspace && (
|
||||
<Button variant="ghost" onClick={() => authClient.signOut()}>
|
||||
{t`Sign out`}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
367
apps/web/src/views/onboarding/workspace-details/index.tsx
Normal file
367
apps/web/src/views/onboarding/workspace-details/index.tsx
Normal file
@@ -0,0 +1,367 @@
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { motion } from "framer-motion";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
HiArrowLeft,
|
||||
HiArrowPath,
|
||||
HiArrowRight,
|
||||
HiCheck,
|
||||
HiEllipsisVertical,
|
||||
HiInformationCircle,
|
||||
HiLockClosed,
|
||||
} from "react-icons/hi2";
|
||||
|
||||
import { authClient } from "@kan/auth/client";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import Input from "~/components/Input";
|
||||
import LoadingSpinner from "~/components/LoadingSpinner";
|
||||
import Toggle from "~/components/Toggle";
|
||||
import { Tooltip } from "~/components/Tooltip";
|
||||
import { useDebounce } from "~/hooks/useDebounce";
|
||||
import { usePopup } from "~/providers/popup";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
function slugify(value: string) {
|
||||
return value
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/[^a-z0-9\s-]/g, "")
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
.slice(0, 60);
|
||||
}
|
||||
|
||||
export default function WorkspaceNameView() {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const plan = searchParams.get("plan") ?? "solo";
|
||||
const billing = searchParams.get("billing") ?? "annual";
|
||||
const returnUrl = searchParams.get("returnUrl") ?? "/boards";
|
||||
const { showPopup } = usePopup();
|
||||
const [isProToggle, setIsProToggle] = useState(plan === "pro");
|
||||
|
||||
const [name, setName] = useState("");
|
||||
const [slug, setSlug] = useState("");
|
||||
const [slugManuallyEdited, setSlugManuallyEdited] = useState(false);
|
||||
const [description, setDescription] = useState("");
|
||||
|
||||
const handleNameChange = (value: string) => {
|
||||
setName(value);
|
||||
if (isProToggle && !slugManuallyEdited) {
|
||||
setSlug(slugify(value));
|
||||
}
|
||||
};
|
||||
|
||||
const [debouncedSlug] = useDebounce(slug, 500);
|
||||
const isTyping = slug !== debouncedSlug;
|
||||
|
||||
const slugAvailability = api.workspace.checkSlugAvailability.useQuery(
|
||||
{ workspaceSlug: debouncedSlug },
|
||||
{ enabled: isProToggle && debouncedSlug.length >= 3 && !isTyping },
|
||||
);
|
||||
|
||||
const isSlugAvailable =
|
||||
slugAvailability.data?.isAvailable && !slugAvailability.data?.isReserved;
|
||||
const isSlugTaken =
|
||||
slugAvailability.data?.isAvailable === false &&
|
||||
!slugAvailability.data?.isReserved;
|
||||
const isSlugReserved = slugAvailability.data?.isReserved === true;
|
||||
|
||||
const slugError = isSlugTaken
|
||||
? t`This URL has already been taken`
|
||||
: isSlugReserved
|
||||
? t`This URL is reserved`
|
||||
: undefined;
|
||||
|
||||
const { data: session } = authClient.useSession();
|
||||
const { data: user } = api.user.getUser.useQuery(undefined, {
|
||||
enabled: !!session?.user,
|
||||
});
|
||||
const { data: workspaces } = api.workspace.all.useQuery();
|
||||
const hasExistingWorkspace = !!workspaces?.length;
|
||||
|
||||
const utils = api.useUtils();
|
||||
|
||||
const previewSlug = isProToggle
|
||||
? slugify(slug) || slugify(name) || "your-workspace"
|
||||
: "your-workspace";
|
||||
|
||||
const createWorkspace = api.workspace.create.useMutation({
|
||||
onSuccess: async (workspace) => {
|
||||
if (!workspace.publicId) return;
|
||||
localStorage.setItem("workspacePublicId", workspace.publicId);
|
||||
void utils.workspace.all.invalidate();
|
||||
router.push("/boards");
|
||||
},
|
||||
onError: () => {
|
||||
showPopup({
|
||||
header: t`Unable to create workspace`,
|
||||
message: t`Please try again later, or contact customer support.`,
|
||||
icon: "error",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const [isRedirectingToCheckout, setIsRedirectingToCheckout] = useState(false);
|
||||
|
||||
const handleContinue = async () => {
|
||||
if (!name.trim()) return;
|
||||
|
||||
if (plan === "solo") {
|
||||
createWorkspace.mutate({
|
||||
name: name.trim(),
|
||||
...(description.trim() && { description: description.trim() }),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// team/pro: redirect to Stripe — workspace created on checkout_success
|
||||
setIsRedirectingToCheckout(true);
|
||||
try {
|
||||
const response = await fetch("/api/stripe/create_checkout_session", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
workspaceName: name.trim(),
|
||||
...(description.trim() && {
|
||||
workspaceDescription: description.trim(),
|
||||
}),
|
||||
...(plan === "pro" && slug ? { workspaceSlug: slug } : {}),
|
||||
cancelUrl: window.location.pathname + window.location.search,
|
||||
successUrl: "/boards",
|
||||
billing,
|
||||
plan,
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
const url = (data as { url: string }).url;
|
||||
if (url) {
|
||||
window.location.href = url;
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// fall through
|
||||
}
|
||||
setIsRedirectingToCheckout(false);
|
||||
showPopup({
|
||||
header: t`Unable to start checkout`,
|
||||
message: t`Please try again later, or contact customer support.`,
|
||||
icon: "error",
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
document.getElementById("workspace-name-input")?.focus();
|
||||
}, []);
|
||||
|
||||
const displayName = user?.name ?? session?.user.name ?? "";
|
||||
|
||||
const BOARDS = [t`Roadmap`, t`Engineering`, t`Marketing`];
|
||||
const [visibleCount, setVisibleCount] = useState(1);
|
||||
|
||||
useEffect(() => {
|
||||
const timers = BOARDS.slice(1).map((_, i) =>
|
||||
setTimeout(() => setVisibleCount(i + 2), (i + 1) * 2000),
|
||||
);
|
||||
return () => timers.forEach(clearTimeout);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col items-center justify-center gap-4 bg-light-100 px-4 py-8 dark:bg-dark-50 md:px-6">
|
||||
<div className="w-full max-w-3xl overflow-hidden rounded-xl border border-light-400 bg-light-200 shadow-xl dark:border-dark-400 dark:bg-dark-100">
|
||||
<div className="flex flex-col md:h-[520px] md:flex-row">
|
||||
{/* Left panel */}
|
||||
<div className="flex flex-col p-6 md:w-[55%] md:p-8">
|
||||
<div className="flex-1">
|
||||
<h2 className="text-xl font-bold text-light-1000 dark:text-dark-1000">
|
||||
{t`Set up your workspace`}
|
||||
</h2>
|
||||
<p className="mt-1 text-sm text-light-800 dark:text-dark-800">
|
||||
{t`You can always change these later in settings.`}
|
||||
</p>
|
||||
|
||||
<div className="mt-6 space-y-3">
|
||||
<Input
|
||||
id="workspace-name-input"
|
||||
placeholder={t`Workspace name`}
|
||||
value={name}
|
||||
onChange={(e) => handleNameChange(e.target.value)}
|
||||
onKeyDown={(e) => e.key === "Enter" && handleContinue()}
|
||||
maxLength={64}
|
||||
/>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Input
|
||||
placeholder={t`your-workspace`}
|
||||
value={isProToggle ? slug : t`your-workspace`}
|
||||
onChange={(e) => {
|
||||
setSlugManuallyEdited(true);
|
||||
setSlug(
|
||||
e.target.value
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9\s-]/g, "")
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/-+/g, "-")
|
||||
.slice(0, 60),
|
||||
);
|
||||
}}
|
||||
disabled={!isProToggle}
|
||||
prefix="kan.bn/"
|
||||
className={
|
||||
!isProToggle ? "cursor-not-allowed opacity-50" : ""
|
||||
}
|
||||
errorMessage={slugError}
|
||||
iconRight={
|
||||
!isProToggle ? (
|
||||
<Tooltip
|
||||
content={
|
||||
<span className="text-xs">{t`Custom usernames require upgrading to a Pro plan`}</span>
|
||||
}
|
||||
placement="top"
|
||||
delay={0}
|
||||
>
|
||||
<HiInformationCircle className="h-4 w-4 leading-[0] text-dark-700 dark:text-dark-700" />
|
||||
</Tooltip>
|
||||
) : isProToggle && slug.length >= 3 ? (
|
||||
isTyping || slugAvailability.isPending ? (
|
||||
<LoadingSpinner />
|
||||
) : isSlugAvailable ? (
|
||||
<HiCheck className="h-4 w-4 text-white" />
|
||||
) : null
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{plan !== "pro" && (
|
||||
<div className="pb-2">
|
||||
<Toggle
|
||||
isChecked={isProToggle}
|
||||
onChange={() => setIsProToggle((v) => !v)}
|
||||
label={t`Upgrade to Pro ($29/month)`}
|
||||
labelPosition="after"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<textarea
|
||||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
placeholder={t`Workspace description`}
|
||||
maxLength={280}
|
||||
rows={3}
|
||||
className="block w-full resize-none rounded-md border-0 bg-dark-300 bg-white/5 py-1.5 text-sm shadow-sm ring-1 ring-inset ring-light-600 placeholder:text-dark-800 focus:ring-2 focus:ring-inset focus:ring-light-700 dark:text-dark-1000 dark:ring-dark-700 dark:focus:ring-dark-700 sm:leading-6"
|
||||
/>
|
||||
<p className="mt-1 text-right text-[10px] text-light-700 dark:text-dark-700">
|
||||
{description.length}/280
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex flex-wrap items-center justify-between gap-3">
|
||||
<div className="ml-auto flex gap-2">
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() =>
|
||||
router.replace(
|
||||
`/onboarding/select-plan?plan=${plan}&billing=${billing}&returnUrl=${encodeURIComponent(returnUrl)}`,
|
||||
)
|
||||
}
|
||||
>
|
||||
{t`Back`}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => void handleContinue()}
|
||||
disabled={
|
||||
!name.trim() ||
|
||||
createWorkspace.isPending ||
|
||||
isRedirectingToCheckout ||
|
||||
(isProToggle &&
|
||||
slug.length >= 3 &&
|
||||
(isTyping || slugAvailability.isPending || !!slugError))
|
||||
}
|
||||
isLoading={
|
||||
createWorkspace.isPending || isRedirectingToCheckout
|
||||
}
|
||||
>
|
||||
{t`Continue`}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right panel — browser mockup */}
|
||||
<div className="hidden flex-col bg-light-300 dark:bg-dark-200 md:flex md:w-[45%]">
|
||||
{/* Browser chrome */}
|
||||
<div className="flex items-center gap-2 border-b border-light-400 px-3 py-2.5 dark:border-dark-400">
|
||||
<div className="flex items-center gap-1.5 text-light-700 dark:text-dark-700">
|
||||
<HiArrowLeft className="h-3.5 w-3.5" />
|
||||
<HiArrowRight className="h-3.5 w-3.5" />
|
||||
<HiArrowPath className="h-3.5 w-3.5" />
|
||||
</div>
|
||||
<div className="flex flex-1 items-center gap-1.5 rounded-md bg-light-200 px-2.5 py-1 dark:bg-dark-300">
|
||||
<HiLockClosed className="h-3 w-3 flex-shrink-0 text-light-700 dark:text-dark-700" />
|
||||
<span className="truncate text-xs text-light-900 dark:text-dark-900">
|
||||
kan.bn/
|
||||
<span className="text-light-1000 dark:text-dark-1000">
|
||||
{previewSlug}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<HiEllipsisVertical className="h-4 w-4 flex-shrink-0 text-light-700 dark:text-dark-700" />
|
||||
</div>
|
||||
|
||||
{/* Browser content */}
|
||||
<div className="flex flex-1 flex-col items-center overflow-hidden px-14 py-8">
|
||||
{/* Workspace name + description */}
|
||||
<p className="text-center text-xs font-bold text-light-1000 dark:text-dark-1000">
|
||||
{name || t`Your workspace`}
|
||||
</p>
|
||||
<p className="mt-0.5 line-clamp-2 break-all text-center text-[10px] text-light-800 dark:text-dark-800">
|
||||
{description || t`Your workspace description`}
|
||||
</p>
|
||||
|
||||
{/* Boards area */}
|
||||
<div className="mt-3 flex w-full flex-1 flex-col rounded-lg bg-light-200 p-2 dark:bg-dark-300">
|
||||
<div className="flex flex-1 flex-col gap-1.5">
|
||||
{BOARDS.map((board, i) => (
|
||||
<motion.div
|
||||
key={board}
|
||||
initial={{ opacity: 0, y: -12 }}
|
||||
animate={
|
||||
i < visibleCount
|
||||
? { opacity: 1, y: 0 }
|
||||
: { opacity: 0, y: -12 }
|
||||
}
|
||||
transition={{
|
||||
opacity: { duration: 0.2 },
|
||||
y: { duration: 0.25, ease: "easeOut" },
|
||||
}}
|
||||
className="flex w-full flex-1 items-center justify-center rounded border border-dashed border-light-400 bg-light-50 px-3 text-[10px] font-medium text-light-900 dark:border-dark-400 dark:bg-dark-100 dark:text-dark-900"
|
||||
>
|
||||
{board}
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<p className="mt-2 text-[10px] font-semibold text-light-900 dark:text-dark-900">
|
||||
kan.bn
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{!hasExistingWorkspace && (
|
||||
<Button variant="ghost" onClick={() => authClient.signOut()}>
|
||||
{t`Sign out`}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -110,18 +110,17 @@ export default function Avatar({
|
||||
const cropYpx = (crop.y / 100) * image.naturalHeight;
|
||||
const cropWpx = (crop.width / 100) * image.naturalWidth;
|
||||
const cropHpx = (crop.height / 100) * image.naturalHeight;
|
||||
canvas.width = Math.max(1, Math.floor(cropWpx));
|
||||
canvas.height = Math.max(1, Math.floor(cropHpx));
|
||||
|
||||
// Cap output at 512x512 — avatars display at 64x64, so higher res is wasteful
|
||||
// and causes "File too large" errors on HiDPI screens
|
||||
const maxSize = 512;
|
||||
const scale = Math.min(maxSize / cropWpx, maxSize / cropHpx, 1);
|
||||
canvas.width = Math.max(1, Math.floor(cropWpx * scale));
|
||||
canvas.height = Math.max(1, Math.floor(cropHpx * scale));
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (!ctx) throw new Error("Canvas not supported");
|
||||
|
||||
// For better quality on HiDPI screens
|
||||
const pixelRatio = window.devicePixelRatio || 1;
|
||||
canvas.width = canvas.width * pixelRatio;
|
||||
canvas.height = canvas.height * pixelRatio;
|
||||
ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
|
||||
ctx.imageSmoothingQuality = "high";
|
||||
|
||||
ctx.drawImage(
|
||||
image,
|
||||
cropXpx,
|
||||
@@ -130,8 +129,8 @@ export default function Avatar({
|
||||
cropHpx,
|
||||
0,
|
||||
0,
|
||||
canvas.width / pixelRatio,
|
||||
canvas.height / pixelRatio,
|
||||
canvas.width,
|
||||
canvas.height,
|
||||
);
|
||||
|
||||
const mime = selectedFile?.type ?? "image/jpeg";
|
||||
@@ -139,6 +138,7 @@ export default function Avatar({
|
||||
canvas.toBlob(
|
||||
(b) => (b ? resolve(b) : reject(new Error("toBlob failed"))),
|
||||
mime,
|
||||
0.85,
|
||||
);
|
||||
});
|
||||
return blob;
|
||||
|
||||
@@ -24,6 +24,8 @@ export function UpgradeToProConfirmation({
|
||||
body: JSON.stringify({
|
||||
...(entityId && { slug: entityId }),
|
||||
workspacePublicId: workspacePublicId,
|
||||
plan: "pro",
|
||||
billing: "monthly",
|
||||
cancelUrl: "/settings",
|
||||
successUrl: "/settings",
|
||||
}),
|
||||
|
||||
@@ -39,6 +39,8 @@ services:
|
||||
|
||||
# Logging (optional - debug, info, warn, error; defaults to debug in dev, info in prod)
|
||||
- LOG_LEVEL=${LOG_LEVEL}
|
||||
- AXIOM_TOKEN=${AXIOM_TOKEN}
|
||||
- AXIOM_DATASET=${AXIOM_DATASET}
|
||||
|
||||
# Stripe
|
||||
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
"types": "./dist/utils/rateLimit.d.ts",
|
||||
"default": "./src/utils/rateLimit.ts"
|
||||
},
|
||||
"./utils/apiLogging": {
|
||||
"types": "./dist/utils/apiLogging.d.ts",
|
||||
"default": "./src/utils/apiLogging.ts"
|
||||
},
|
||||
"./utils/permissions": {
|
||||
"types": "./dist/utils/permissions.d.ts",
|
||||
"default": "./src/utils/permissions.ts"
|
||||
|
||||
@@ -227,7 +227,7 @@ export const boardRouter = createTRPCRouter({
|
||||
boardSlug: z
|
||||
.string()
|
||||
.min(3)
|
||||
.max(24)
|
||||
.max(60)
|
||||
.regex(/^(?![-]+$)[a-zA-Z0-9-]+$/),
|
||||
members: z.array(z.string().min(12)).optional(),
|
||||
labels: z.array(z.string().min(12)).optional(),
|
||||
@@ -657,7 +657,7 @@ export const boardRouter = createTRPCRouter({
|
||||
boardSlug: z
|
||||
.string()
|
||||
.min(3)
|
||||
.max(24)
|
||||
.max(60)
|
||||
.regex(/^(?![-]+$)[a-zA-Z0-9-]+$/),
|
||||
boardPublicId: z.string().min(12),
|
||||
}),
|
||||
|
||||
@@ -4,6 +4,7 @@ import { z } from "zod";
|
||||
import * as cardRepo from "@kan/db/repository/card.repo";
|
||||
import * as cardActivityRepo from "@kan/db/repository/cardActivity.repo";
|
||||
import * as cardCommentRepo from "@kan/db/repository/cardComment.repo";
|
||||
import * as checklistRepo from "@kan/db/repository/checklist.repo";
|
||||
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";
|
||||
@@ -1184,4 +1185,176 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
return { success: true };
|
||||
}),
|
||||
duplicate: protectedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
summary: "Duplicate a card",
|
||||
method: "POST",
|
||||
path: "/cards/{cardPublicId}/duplicate",
|
||||
description: "Duplicates a card to a target list with optional options",
|
||||
tags: ["Cards"],
|
||||
protect: true,
|
||||
},
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
cardPublicId: z.string().min(12),
|
||||
listPublicId: z.string().min(12),
|
||||
index: z.number().int().min(0).optional(),
|
||||
title: z.string().min(1).max(2000).optional(),
|
||||
copyLabels: z.boolean(),
|
||||
copyMembers: z.boolean(),
|
||||
copyChecklists: z.boolean(),
|
||||
}),
|
||||
)
|
||||
.output(
|
||||
z.object({
|
||||
publicId: z.string(),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId)
|
||||
throw new TRPCError({
|
||||
message: `User not authenticated`,
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const sourceCardMeta = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
|
||||
ctx.db,
|
||||
input.cardPublicId,
|
||||
);
|
||||
|
||||
if (!sourceCardMeta)
|
||||
throw new TRPCError({
|
||||
message: `Card with public ID ${input.cardPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertPermission(
|
||||
ctx.db,
|
||||
userId,
|
||||
sourceCardMeta.workspaceId,
|
||||
"card:create",
|
||||
);
|
||||
|
||||
const targetList = await listRepo.getWorkspaceAndListIdByListPublicId(
|
||||
ctx.db,
|
||||
input.listPublicId,
|
||||
);
|
||||
|
||||
if (!targetList)
|
||||
throw new TRPCError({
|
||||
message: `List with public ID ${input.listPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
if (targetList.workspaceId !== sourceCardMeta.workspaceId)
|
||||
throw new TRPCError({
|
||||
message: `Target list must be in the same workspace`,
|
||||
code: "BAD_REQUEST",
|
||||
});
|
||||
|
||||
const sourceCard = await cardRepo.getWithListAndMembersByPublicId(
|
||||
ctx.db,
|
||||
input.cardPublicId,
|
||||
);
|
||||
|
||||
if (!sourceCard)
|
||||
throw new TRPCError({
|
||||
message: `Card with public ID ${input.cardPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
const newCard = await cardRepo.create(ctx.db, {
|
||||
title: input.title ?? sourceCard.title,
|
||||
description: sourceCard.description ?? "",
|
||||
createdBy: userId,
|
||||
listId: targetList.id,
|
||||
position: "end",
|
||||
dueDate: sourceCard.dueDate ?? null,
|
||||
});
|
||||
|
||||
if (input.index !== undefined && input.index >= 0) {
|
||||
await cardRepo.reorder(ctx.db, {
|
||||
cardId: newCard.id,
|
||||
newIndex: input.index,
|
||||
newListId: targetList.id,
|
||||
});
|
||||
}
|
||||
|
||||
if (input.copyLabels && sourceCard.labels?.length) {
|
||||
const labelPublicIds = sourceCard.labels.map((l) => l.publicId);
|
||||
const labels = await labelRepo.getAllByPublicIds(ctx.db, labelPublicIds);
|
||||
if (labels.length) {
|
||||
const labelsInsert = labels.map((label) => ({
|
||||
cardId: newCard.id,
|
||||
labelId: label.id,
|
||||
}));
|
||||
await cardRepo.bulkCreateCardLabelRelationships(ctx.db, labelsInsert);
|
||||
const cardActivitesInsert = labels.map((cardLabel) => ({
|
||||
type: "card.updated.label.added" as const,
|
||||
cardId: newCard.id,
|
||||
labelId: cardLabel.id,
|
||||
createdBy: userId,
|
||||
}));
|
||||
await cardActivityRepo.bulkCreate(ctx.db, cardActivitesInsert);
|
||||
}
|
||||
}
|
||||
|
||||
if (input.copyMembers && sourceCard.members?.length) {
|
||||
const memberPublicIds = sourceCard.members.map((m) => m.publicId);
|
||||
const members = await workspaceRepo.getAllMembersByPublicIds(
|
||||
ctx.db,
|
||||
memberPublicIds,
|
||||
);
|
||||
if (members.length) {
|
||||
const membersInsert = members.map((member) => ({
|
||||
cardId: newCard.id,
|
||||
workspaceMemberId: member.id,
|
||||
}));
|
||||
await cardRepo.bulkCreateCardWorkspaceMemberRelationships(
|
||||
ctx.db,
|
||||
membersInsert,
|
||||
);
|
||||
const cardActivitesInsert = members.map((member) => ({
|
||||
type: "card.updated.member.added" as const,
|
||||
cardId: newCard.id,
|
||||
workspaceMemberId: member.id,
|
||||
createdBy: userId,
|
||||
}));
|
||||
await cardActivityRepo.bulkCreate(ctx.db, cardActivitesInsert);
|
||||
}
|
||||
}
|
||||
|
||||
if (input.copyChecklists && sourceCard.checklists?.length) {
|
||||
for (const checklist of sourceCard.checklists) {
|
||||
const newChecklist = await checklistRepo.create(ctx.db, {
|
||||
cardId: newCard.id,
|
||||
name: checklist.name,
|
||||
createdBy: userId,
|
||||
});
|
||||
if (!newChecklist?.id) continue;
|
||||
if (checklist.items?.length) {
|
||||
for (const item of checklist.items) {
|
||||
await checklistRepo.createItem(ctx.db, {
|
||||
checklistId: newChecklist.id,
|
||||
title: item.title,
|
||||
createdBy: userId,
|
||||
completed: item.completed ?? false,
|
||||
});
|
||||
}
|
||||
}
|
||||
await cardActivityRepo.create(ctx.db, {
|
||||
type: "card.updated.checklist.added",
|
||||
cardId: newCard.id,
|
||||
toTitle: newChecklist.name,
|
||||
createdBy: userId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return { publicId: newCard.publicId };
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@ import { encryptToken } from "../utils/encryption";
|
||||
export const integrationRouter = createTRPCRouter({
|
||||
saveGitHubToken: protectedProcedure
|
||||
.input(z.object({ token: z.string() }))
|
||||
.output(z.object({ success: z.boolean() }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const user = ctx.user;
|
||||
|
||||
@@ -43,7 +44,9 @@ export const integrationRouter = createTRPCRouter({
|
||||
return { success: true };
|
||||
}),
|
||||
|
||||
disconnectGitHub: protectedProcedure.mutation(async ({ ctx }) => {
|
||||
disconnectGitHub: protectedProcedure
|
||||
.output(z.object({ success: z.boolean() }))
|
||||
.mutation(async ({ ctx }) => {
|
||||
const user = ctx.user;
|
||||
|
||||
if (!user)
|
||||
@@ -56,7 +59,9 @@ export const integrationRouter = createTRPCRouter({
|
||||
return { success: true };
|
||||
}),
|
||||
|
||||
getGitHubStatus: protectedProcedure.query(async ({ ctx }) => {
|
||||
getGitHubStatus: protectedProcedure
|
||||
.output(z.object({ connected: z.boolean() }))
|
||||
.query(async ({ ctx }) => {
|
||||
const user = ctx.user;
|
||||
|
||||
if (!user)
|
||||
|
||||
@@ -202,6 +202,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
.input(
|
||||
z.object({
|
||||
name: z.string().min(1).max(64),
|
||||
description: z.string().max(280).optional(),
|
||||
slug: z
|
||||
.string()
|
||||
.min(3)
|
||||
@@ -260,6 +261,7 @@ export const workspaceRouter = createTRPCRouter({
|
||||
slug: workspaceSlug,
|
||||
createdBy: userId,
|
||||
createdByEmail: userEmail,
|
||||
...(input.description && { description: input.description }),
|
||||
});
|
||||
|
||||
if (!result.publicId)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { randomUUID } from "crypto";
|
||||
import type { CreateNextContextOptions } from "@trpc/server/adapters/next";
|
||||
import type { NextApiRequest } from "next";
|
||||
import type { OpenApiMeta } from "trpc-to-openapi";
|
||||
@@ -11,7 +12,28 @@ import { initAuth } from "@kan/auth/server";
|
||||
import { createDrizzleClient } from "@kan/db/client";
|
||||
import { createLogger } from "@kan/logger";
|
||||
|
||||
const log = createLogger("trpc");
|
||||
const log = createLogger("api");
|
||||
|
||||
const TRPC_STATUS_MAP: Partial<Record<TRPCError["code"], number>> = {
|
||||
PARSE_ERROR: 400,
|
||||
BAD_REQUEST: 400,
|
||||
UNAUTHORIZED: 401,
|
||||
FORBIDDEN: 403,
|
||||
NOT_FOUND: 404,
|
||||
METHOD_NOT_SUPPORTED: 405,
|
||||
TIMEOUT: 408,
|
||||
CONFLICT: 409,
|
||||
PRECONDITION_FAILED: 412,
|
||||
PAYLOAD_TOO_LARGE: 413,
|
||||
UNPROCESSABLE_CONTENT: 422,
|
||||
TOO_MANY_REQUESTS: 429,
|
||||
CLIENT_CLOSED_REQUEST: 499,
|
||||
INTERNAL_SERVER_ERROR: 500,
|
||||
NOT_IMPLEMENTED: 501,
|
||||
BAD_GATEWAY: 502,
|
||||
SERVICE_UNAVAILABLE: 503,
|
||||
GATEWAY_TIMEOUT: 504,
|
||||
};
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
@@ -50,6 +72,7 @@ interface CreateContextOptions {
|
||||
db: dbClient;
|
||||
auth: ReturnType<typeof createAuthWithHeaders>;
|
||||
headers: Headers;
|
||||
transport?: "trpc" | "rest";
|
||||
}
|
||||
|
||||
export const createInnerTRPCContext = (opts: CreateContextOptions) => {
|
||||
@@ -58,6 +81,8 @@ export const createInnerTRPCContext = (opts: CreateContextOptions) => {
|
||||
db: opts.db,
|
||||
auth: opts.auth,
|
||||
headers: opts.headers,
|
||||
transport: opts.transport ?? "trpc",
|
||||
requestId: randomUUID(),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -69,7 +94,13 @@ export const createTRPCContext = async ({ req }: CreateNextContextOptions) => {
|
||||
|
||||
const session = await auth.api.getSession();
|
||||
|
||||
return createInnerTRPCContext({ db, user: session?.user, auth, headers });
|
||||
return createInnerTRPCContext({
|
||||
db,
|
||||
user: session?.user,
|
||||
auth,
|
||||
headers,
|
||||
transport: "trpc",
|
||||
});
|
||||
};
|
||||
|
||||
export const createNextApiContext = async (req: NextApiRequest) => {
|
||||
@@ -80,7 +111,13 @@ export const createNextApiContext = async (req: NextApiRequest) => {
|
||||
|
||||
const session = await auth.api.getSession();
|
||||
|
||||
return createInnerTRPCContext({ db, user: session?.user, auth, headers });
|
||||
return createInnerTRPCContext({
|
||||
db,
|
||||
user: session?.user,
|
||||
auth,
|
||||
headers,
|
||||
transport: "trpc",
|
||||
});
|
||||
};
|
||||
|
||||
export const createRESTContext = async ({ req }: CreateNextContextOptions) => {
|
||||
@@ -93,11 +130,16 @@ export const createRESTContext = async ({ req }: CreateNextContextOptions) => {
|
||||
try {
|
||||
session = await auth.api.getSession();
|
||||
} catch (error) {
|
||||
log.error({ err: error }, "Error getting session");
|
||||
throw error;
|
||||
log.warn({ err: error }, "Failed to get session, treating as unauthenticated");
|
||||
}
|
||||
|
||||
return createInnerTRPCContext({ db, user: session?.user, auth, headers });
|
||||
return createInnerTRPCContext({
|
||||
db,
|
||||
user: session?.user,
|
||||
auth,
|
||||
headers,
|
||||
transport: "rest",
|
||||
});
|
||||
};
|
||||
|
||||
const t = initTRPC
|
||||
@@ -121,25 +163,45 @@ export const createTRPCRouter = t.router;
|
||||
|
||||
export const createCallerFactory = t.createCallerFactory;
|
||||
|
||||
const loggingMiddleware = t.middleware(async ({ path, type, next, ctx }) => {
|
||||
const loggingMiddleware = t.middleware(async ({ path, type, next, ctx, getRawInput }) => {
|
||||
const start = Date.now();
|
||||
const result = await next();
|
||||
const [result, input] = await Promise.all([next(), getRawInput().catch(() => undefined)]);
|
||||
const duration = Date.now() - start;
|
||||
|
||||
const meta = { procedure: path, type, duration, userId: (ctx as { user?: { id: string } }).user?.id };
|
||||
const { user, transport, requestId } = ctx as {
|
||||
user?: { id: string; email: string };
|
||||
transport?: string;
|
||||
requestId?: string;
|
||||
};
|
||||
const isCloud = process.env.NEXT_PUBLIC_KAN_ENV === "cloud";
|
||||
const meta = {
|
||||
requestId,
|
||||
procedure: path,
|
||||
type,
|
||||
transport,
|
||||
duration,
|
||||
userId: user?.id,
|
||||
...(isCloud && { email: user?.email }),
|
||||
input,
|
||||
};
|
||||
|
||||
const label = transport === "rest" ? "REST" : "tRPC";
|
||||
|
||||
if (result.ok) {
|
||||
log.info(meta, "tRPC OK");
|
||||
log.info({ ...meta, status: 200 }, `${label} OK`);
|
||||
} else {
|
||||
log.error({ ...meta, err: result.error }, "tRPC error");
|
||||
const status = TRPC_STATUS_MAP[result.error.code] ?? 500;
|
||||
const errorCode = result.error.code;
|
||||
log.error(
|
||||
{ ...meta, status, errorCode, err: result.error },
|
||||
`${label} error`,
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
export const publicProcedure = t.procedure.use(loggingMiddleware).meta({
|
||||
openapi: { method: "GET", path: "/public" },
|
||||
});
|
||||
export const publicProcedure = t.procedure.use(loggingMiddleware);
|
||||
|
||||
const enforceUserIsAuthed = t.middleware(async ({ ctx, next }) => {
|
||||
if (!ctx.user) {
|
||||
@@ -163,13 +225,7 @@ const enforceUserIsAdmin = t.middleware(async ({ ctx, next }) => {
|
||||
|
||||
export const protectedProcedure = t.procedure
|
||||
.use(loggingMiddleware)
|
||||
.use(enforceUserIsAuthed)
|
||||
.meta({
|
||||
openapi: {
|
||||
method: "GET",
|
||||
path: "/protected",
|
||||
},
|
||||
});
|
||||
.use(enforceUserIsAuthed);
|
||||
|
||||
export const adminProtectedProcedure = t.procedure
|
||||
.use(loggingMiddleware)
|
||||
|
||||
80
packages/api/src/utils/apiLogging.ts
Normal file
80
packages/api/src/utils/apiLogging.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { randomUUID } from "crypto";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { createLogger } from "@kan/logger";
|
||||
|
||||
import { createNextApiContext } from "../trpc";
|
||||
|
||||
const log = createLogger("api");
|
||||
|
||||
const isCloud = process.env.NEXT_PUBLIC_KAN_ENV === "cloud";
|
||||
|
||||
export function withApiLogging(
|
||||
handler: (
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) => Promise<unknown> | unknown,
|
||||
) {
|
||||
return async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const start = Date.now();
|
||||
const requestId = randomUUID();
|
||||
const route = req.url?.split("?")[0] ?? "unknown";
|
||||
const input = {
|
||||
...(req.query &&
|
||||
Object.keys(req.query).length > 0 && { query: req.query }),
|
||||
...(req.body &&
|
||||
typeof req.body === "object" &&
|
||||
Object.keys(req.body).length > 0 && { body: req.body }),
|
||||
};
|
||||
|
||||
let statusCode = 200;
|
||||
const originalStatus = res.status.bind(res);
|
||||
res.status = (code: number) => {
|
||||
statusCode = code;
|
||||
return originalStatus(code);
|
||||
};
|
||||
|
||||
let userId: string | undefined;
|
||||
let email: string | undefined;
|
||||
try {
|
||||
const ctx = await createNextApiContext(req);
|
||||
userId = ctx.user?.id;
|
||||
email = ctx.user?.email ?? undefined;
|
||||
} catch {
|
||||
// unauthenticated or auth unavailable
|
||||
}
|
||||
|
||||
let handlerError: unknown;
|
||||
try {
|
||||
await handler(req, res);
|
||||
} catch (err) {
|
||||
handlerError = err;
|
||||
statusCode = 500;
|
||||
if (!res.headersSent) {
|
||||
res.status(500).json({ error: "Internal server error" });
|
||||
}
|
||||
}
|
||||
|
||||
const duration = Date.now() - start;
|
||||
const meta = {
|
||||
requestId,
|
||||
procedure: route,
|
||||
transport: "rest",
|
||||
duration,
|
||||
userId,
|
||||
...(isCloud && email && { email }),
|
||||
...(Object.keys(input).length > 0 && { input }),
|
||||
status: statusCode,
|
||||
...(handlerError instanceof Error && {
|
||||
error: handlerError.message,
|
||||
stack: handlerError.stack,
|
||||
}),
|
||||
};
|
||||
|
||||
if (statusCode < 400) {
|
||||
log.info(meta, "API OK");
|
||||
} else {
|
||||
log.error(meta, "API error");
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -165,6 +165,13 @@ export function createPlugins(db: dbClient) {
|
||||
: []),
|
||||
apiKey({
|
||||
enableSessionForAPIKeys: true,
|
||||
customAPIKeyGetter: (ctx) => {
|
||||
const authorization = ctx.headers?.get("authorization");
|
||||
if (authorization?.startsWith("Bearer ")) {
|
||||
return authorization.slice(7);
|
||||
}
|
||||
return ctx.headers?.get("x-api-key") ?? undefined;
|
||||
},
|
||||
rateLimit: {
|
||||
enabled: true,
|
||||
timeWindow: 1000 * 60, // 1 minute
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TYPE "public"."workspace_plan" ADD VALUE 'team' BEFORE 'pro';
|
||||
3869
packages/db/migrations/meta/20260402225628_snapshot.json
Normal file
3869
packages/db/migrations/meta/20260402225628_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -218,6 +218,13 @@
|
||||
"when": 1773212242728,
|
||||
"tag": "20260311065722_AddWeekStartDay",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 31,
|
||||
"version": "7",
|
||||
"when": 1775170588247,
|
||||
"tag": "20260402225628_AddTeamWorkspacePlan",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -64,6 +64,8 @@ export const create = async (
|
||||
slug: string;
|
||||
createdBy: string;
|
||||
createdByEmail: string;
|
||||
description?: string;
|
||||
plan?: "free" | "team" | "pro" | "enterprise";
|
||||
},
|
||||
) => {
|
||||
const [workspace] = await db
|
||||
@@ -73,6 +75,8 @@ export const create = async (
|
||||
name: workspaceInput.name,
|
||||
slug: workspaceInput.slug,
|
||||
createdBy: workspaceInput.createdBy,
|
||||
...(workspaceInput.description && { description: workspaceInput.description }),
|
||||
...(workspaceInput.plan && { plan: workspaceInput.plan }),
|
||||
})
|
||||
.returning({
|
||||
id: workspaces.id,
|
||||
@@ -124,7 +128,7 @@ export const update = async (
|
||||
workspaceInput: {
|
||||
name?: string;
|
||||
slug?: string;
|
||||
plan?: "free" | "pro" | "enterprise";
|
||||
plan?: "free" | "team" | "pro" | "enterprise";
|
||||
description?: string;
|
||||
showEmailsToMembers?: boolean;
|
||||
weekStartDay?: number;
|
||||
|
||||
@@ -34,7 +34,7 @@ export const slugTypes = ["reserved", "premium"] as const;
|
||||
export type SlugType = (typeof slugTypes)[number];
|
||||
export const slugTypeEnum = pgEnum("slug_type", slugTypes);
|
||||
|
||||
export const workspacePlans = ["free", "pro", "enterprise"] as const;
|
||||
export const workspacePlans = ["free", "team", "pro", "enterprise"] as const;
|
||||
export type WorkspacePlan = (typeof workspacePlans)[number];
|
||||
export const workspacePlanEnum = pgEnum("workspace_plan", workspacePlans);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
|
||||
},
|
||||
"dependencies": {
|
||||
"@axiomhq/js": "^1.4.0",
|
||||
"pino": "^9.14.0",
|
||||
"pino-pretty": "^13.1.3"
|
||||
},
|
||||
|
||||
@@ -1,20 +1,43 @@
|
||||
import { Axiom } from "@axiomhq/js";
|
||||
import pino from "pino";
|
||||
|
||||
const isDev = process.env.NODE_ENV !== "production";
|
||||
const isCloud = process.env.NEXT_PUBLIC_KAN_ENV === "cloud";
|
||||
const level = process.env.LOG_LEVEL || (isDev ? "debug" : "info");
|
||||
|
||||
export const logger = pino({
|
||||
level,
|
||||
...(isDev && {
|
||||
transport: {
|
||||
target: "pino-pretty",
|
||||
options: {
|
||||
colorize: true,
|
||||
ignore: "pid,hostname",
|
||||
translateTime: "HH:MM:ss",
|
||||
},
|
||||
const axiomToken = process.env.AXIOM_TOKEN;
|
||||
const axiomDataset = process.env.AXIOM_DATASET;
|
||||
const useAxiom = isCloud && !!axiomToken && !!axiomDataset;
|
||||
|
||||
function createAxiomStream(token: string, dataset: string): pino.DestinationStream {
|
||||
const client = new Axiom({ token });
|
||||
return {
|
||||
write(msg: string) {
|
||||
try {
|
||||
client.ingest(dataset, [JSON.parse(msg) as Record<string, unknown>]);
|
||||
} catch {
|
||||
// ignore malformed log lines
|
||||
}
|
||||
},
|
||||
}),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export const logger = useAxiom
|
||||
? pino(
|
||||
{ level },
|
||||
pino.multistream([
|
||||
{ stream: process.stdout, level },
|
||||
{ stream: createAxiomStream(axiomToken, axiomDataset), level },
|
||||
]),
|
||||
)
|
||||
: pino({
|
||||
level,
|
||||
...(isDev && {
|
||||
transport: {
|
||||
target: "pino-pretty",
|
||||
options: { colorize: true, ignore: "pid,hostname", translateTime: "HH:MM:ss" },
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
export const createLogger = (module: string) => logger.child({ module });
|
||||
|
||||
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
@@ -504,6 +504,9 @@ importers:
|
||||
|
||||
packages/logger:
|
||||
dependencies:
|
||||
'@axiomhq/js':
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0
|
||||
pino:
|
||||
specifier: ^9.14.0
|
||||
version: 9.14.0
|
||||
@@ -891,6 +894,10 @@ packages:
|
||||
resolution: {integrity: sha512-kLO7k7cGJ6KaHiExSJWojZurF7SnGMDHXRuQunFnEoD0n1yB6Lqy/S/zHiQ7oJnBhPr9q0TW9qFkrsZb1Uc54w==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
|
||||
'@axiomhq/js@1.4.0':
|
||||
resolution: {integrity: sha512-wC5x1ud/QJMstrjpicATkyY8+ZVWEl4WlXMtA5EZf7hkj0+b191yv4yynLxLEfr/MveXora9m6CWdJq4DsbcAg==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
'@babel/code-frame@7.27.1':
|
||||
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -5628,6 +5635,9 @@ packages:
|
||||
picomatch:
|
||||
optional: true
|
||||
|
||||
fetch-retry@6.0.0:
|
||||
resolution: {integrity: sha512-BUFj1aMubgib37I3v4q78fYo63Po7t4HUPTpQ6/QE6yK6cIQrP+W43FYToeTEyg5m2Y7eFUtijUuAv/PDlWuag==}
|
||||
|
||||
fflate@0.4.8:
|
||||
resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==}
|
||||
|
||||
@@ -9384,6 +9394,10 @@ snapshots:
|
||||
'@smithy/types': 4.3.2
|
||||
tslib: 2.8.1
|
||||
|
||||
'@axiomhq/js@1.4.0':
|
||||
dependencies:
|
||||
fetch-retry: 6.0.0
|
||||
|
||||
'@babel/code-frame@7.27.1':
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.27.1
|
||||
@@ -14403,6 +14417,8 @@ snapshots:
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.3
|
||||
|
||||
fetch-retry@6.0.0: {}
|
||||
|
||||
fflate@0.4.8: {}
|
||||
|
||||
figures@3.2.0:
|
||||
|
||||
@@ -130,7 +130,9 @@
|
||||
"NOVU_API_KEY",
|
||||
"EMAIL_UNSUBSCRIBE_SECRET",
|
||||
"REDIS_URL",
|
||||
"LOG_LEVEL"
|
||||
"LOG_LEVEL",
|
||||
"AXIOM_TOKEN",
|
||||
"AXIOM_DATASET"
|
||||
],
|
||||
"globalPassThroughEnv": [
|
||||
"NODE_ENV",
|
||||
|
||||
Reference in New Issue
Block a user