UBERF-8353: Reduce number of asyncs (#6806)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2024-10-05 01:19:31 +07:00 committed by GitHub
parent 90f4d02f71
commit 92bb848761
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
51 changed files with 569 additions and 340 deletions

View File

@ -54,8 +54,8 @@ dependencies:
specifier: ^7.3.1
version: 7.5.1
'@playwright/test':
specifier: ^1.41.2
version: 1.41.2
specifier: ^1.47.2
version: 1.47.2
'@rush-temp/account':
specifier: file:./projects/account.tgz
version: file:projects/account.tgz(@types/node@20.11.19)(esbuild@0.20.1)(ts-node@10.9.2)
@ -1376,9 +1376,12 @@ dependencies:
'@vercel/webpack-asset-relocator-loader':
specifier: ^1.7.3
version: 1.7.4
allure-js-commons:
specifier: ^3.0.4
version: 3.0.4(allure-playwright@3.0.4)
allure-playwright:
specifier: ^2.9.2
version: 2.12.2
specifier: ^3.0.4
version: 3.0.4(@playwright/test@1.47.2)
autolinker:
specifier: 4.0.0
version: 4.0.0
@ -1724,6 +1727,9 @@ dependencies:
pdfjs-dist:
specifier: 2.12.313
version: 2.12.313
pg:
specifier: 8.12.0
version: 8.12.0
png-chunks-extract:
specifier: ^1.0.0
version: 1.0.0
@ -6060,12 +6066,12 @@ packages:
dev: false
optional: true
/@playwright/test@1.41.2:
resolution: {integrity: sha512-qQB9h7KbibJzrDpkXkYvsmiDJK14FULCCZgEcoe2AvFAS64oCirWTwzTlAYEbKaRxWs5TFesE1Na6izMv3HfGg==}
engines: {node: '>=16'}
/@playwright/test@1.47.2:
resolution: {integrity: sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==}
engines: {node: '>=18'}
hasBin: true
dependencies:
playwright: 1.41.2
playwright: 1.47.2
dev: false
/@polka/url@1.0.0-next.24:
@ -10563,17 +10569,25 @@ packages:
require-from-string: 2.0.2
dev: false
/allure-js-commons@2.12.2:
resolution: {integrity: sha512-bapkOHuwOYFR62aeNNwFmf8+LZSchzQ4Q8cFXWvEqP5fBTgADA+GujsRl936gjmTmKWVmKYwQfUt+PZw6tgFzw==}
/allure-js-commons@3.0.4(allure-playwright@3.0.4):
resolution: {integrity: sha512-/UgTzpd7a16t8WpkA/25acmkk8xwwYUK3YDeVcZb1+3+7HHZRE943ZlKxUF/LCeLrZEFgYmOtma9xmaHagSddw==}
peerDependencies:
allure-playwright: 3.0.4
peerDependenciesMeta:
allure-playwright:
optional: true
dependencies:
properties: 1.2.1
strip-ansi: 5.2.0
allure-playwright: 3.0.4(@playwright/test@1.47.2)
md5: 2.3.0
dev: false
/allure-playwright@2.12.2:
resolution: {integrity: sha512-QvDyCHABYlZ02PyGevbBZc9tS+Li0zXhTaTC1IJ2wJrd8q9cSS3mUnzAJUjPUuCtofdLBwePd2AuzsYE2ZXEJQ==}
/allure-playwright@3.0.4(@playwright/test@1.47.2):
resolution: {integrity: sha512-P2QBUZfEtqof3PLonVXcO2BdaYmWKGRDy4Ehl4dcAGsXdfS5QdrNat+DmR5BMxBNQgvf1805fGBeZh2Zn0gagQ==}
peerDependencies:
'@playwright/test': '>=1.36.0'
dependencies:
allure-js-commons: 2.12.2
'@playwright/test': 1.47.2
allure-js-commons: 3.0.4(allure-playwright@3.0.4)
dev: false
/ansi-colors@4.1.3:
@ -10604,11 +10618,6 @@ packages:
engines: {node: '>=4'}
dev: false
/ansi-regex@4.1.1:
resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==}
engines: {node: '>=6'}
dev: false
/ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
@ -11751,6 +11760,10 @@ packages:
engines: {node: '>=10'}
dev: false
/charenc@0.0.2:
resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==}
dev: false
/cheerio@0.22.0:
resolution: {integrity: sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==}
engines: {node: '>= 0.6'}
@ -12398,6 +12411,10 @@ packages:
which: 2.0.2
dev: false
/crypt@0.0.2:
resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==}
dev: false
/crypto-js@4.2.0:
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
dev: false
@ -16391,6 +16408,10 @@ packages:
has-tostringtag: 1.0.2
dev: false
/is-buffer@1.1.6:
resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
dev: false
/is-callable@1.2.7:
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
engines: {node: '>= 0.4'}
@ -18387,6 +18408,14 @@ packages:
dev: false
optional: true
/md5@2.3.0:
resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==}
dependencies:
charenc: 0.0.2
crypt: 0.0.2
is-buffer: 1.1.6
dev: false
/mdast-util-definitions@4.0.0:
resolution: {integrity: sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==}
dependencies:
@ -20123,18 +20152,18 @@ packages:
find-up: 3.0.0
dev: false
/playwright-core@1.41.2:
resolution: {integrity: sha512-VaTvwCA4Y8kxEe+kfm2+uUUw5Lubf38RxF7FpBxLPmGe5sdNkSg5e3ChEigaGrX7qdqT3pt2m/98LiyvU2x6CA==}
engines: {node: '>=16'}
/playwright-core@1.47.2:
resolution: {integrity: sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==}
engines: {node: '>=18'}
hasBin: true
dev: false
/playwright@1.41.2:
resolution: {integrity: sha512-v0bOa6H2GJChDL8pAeLa/LZC4feoAMbSQm1/jF/ySsWWoaNItvrMP7GEkvEEFyCTUYKMxjQKaTSg5up7nR6/8A==}
engines: {node: '>=16'}
/playwright@1.47.2:
resolution: {integrity: sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==}
engines: {node: '>=18'}
hasBin: true
dependencies:
playwright-core: 1.41.2
playwright-core: 1.47.2
optionalDependencies:
fsevents: 2.3.2
dev: false
@ -20501,11 +20530,6 @@ packages:
react-is: 16.13.1
dev: false
/properties@1.2.1:
resolution: {integrity: sha512-qYNxyMj1JeW54i/EWEFsM1cVwxJbtgPp8+0Wg9XjNaK6VE/c4oRi6PNu5p7w1mNXEIQIjV5Wwn8v8Gz82/QzdQ==}
engines: {node: '>=0.10'}
dev: false
/prosemirror-changeset@2.2.1:
resolution: {integrity: sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==}
dependencies:
@ -22400,13 +22424,6 @@ packages:
ansi-regex: 3.0.1
dev: false
/strip-ansi@5.2.0:
resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==}
engines: {node: '>=6'}
dependencies:
ansi-regex: 4.1.1
dev: false
/strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
@ -24945,7 +24962,7 @@ packages:
dev: false
file:projects/account.tgz(@types/node@20.11.19)(esbuild@0.20.1)(ts-node@10.9.2):
resolution: {integrity: sha512-bbpUd2zTOQEGPo6LCVfEp6pEiTxJrOXKHPmgVroenH1xPt7DuZWb3HRVym5E39Acx4vUMd85ySKNlmJKMCE0ZQ==, tarball: file:projects/account.tgz}
resolution: {integrity: sha512-dp4BS+teiLPEg/gxddOhYSuaxjuzascxr49DMYfpm4OZEFHdTOHlO3bJXGddaDLgCbT4OcG77W0rdFo38T5/bA==, tarball: file:projects/account.tgz}
id: file:projects/account.tgz
name: '@rush-temp/account'
version: 0.0.0
@ -25099,7 +25116,7 @@ packages:
dev: false
file:projects/ai-bot-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2):
resolution: {integrity: sha512-kUT09zDslxlN/ni38NdRvzE4WtOBOtKbqKqTNvTDP78hcjh7rT3CnWpMUQGnDNI5rzQWiVAaWoHKf2LAHFolRQ==, tarball: file:projects/ai-bot-resources.tgz}
resolution: {integrity: sha512-VUzWp9Le++agPkh/Sq5V8y1LHVSofd+WOJNwkYFDWlJH0+TKM1F88CFBANOYUlg2ZvhOQGyLCCFTcjbPohfnSQ==, tarball: file:projects/ai-bot-resources.tgz}
id: file:projects/ai-bot-resources.tgz
name: '@rush-temp/ai-bot-resources'
version: 0.0.0
@ -25384,7 +25401,7 @@ packages:
dev: false
file:projects/attachment-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2):
resolution: {integrity: sha512-yEPWonMOvXhIk5+IaNQVsyw6wnfqdcB/4UsEh8BLCQwhpepBeVrNSXgS+mLspQaL9g15E81PHwyrWyF1OcqQOQ==, tarball: file:projects/attachment-resources.tgz}
resolution: {integrity: sha512-+/KTqroAiloV0TUV9iGmUInkS19oAY6pZ4cs/eeiOjX8ZIuLN/O7j1rbhldscXI1ZqmEYFtjTFKAxy7qMu21KQ==, tarball: file:projects/attachment-resources.tgz}
id: file:projects/attachment-resources.tgz
name: '@rush-temp/attachment-resources'
version: 0.0.0
@ -25430,7 +25447,7 @@ packages:
dev: false
file:projects/attachment.tgz(@types/node@20.11.19)(esbuild@0.20.1)(ts-node@10.9.2):
resolution: {integrity: sha512-WiT8xtpwwGxmbvGxcHOH8JGj7rZqvwEmaEdTQeHMv/i3fRzT082qjXooTEKrcuMS6e5t33YosRJlq1X1NypNKQ==, tarball: file:projects/attachment.tgz}
resolution: {integrity: sha512-AOC7vKQzBuyM3NGVPnc8wLlrnvf6ve7CT/v4pNBI3ZC5DLXRHkeu4EhUmEujtM0dSUWXukGFnTpgjBYxr2b8Ww==, tarball: file:projects/attachment.tgz}
id: file:projects/attachment.tgz
name: '@rush-temp/attachment'
version: 0.0.0
@ -26213,7 +26230,7 @@ packages:
dev: false
file:projects/contact-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2):
resolution: {integrity: sha512-MzZXj700B09rHWIeXhV8qKlv9OTeZvERBG/Clv+H6OyU9CR03EZpiYEYM725EjYKMTvso1XWsYbjEBfwBi0LYg==, tarball: file:projects/contact-resources.tgz}
resolution: {integrity: sha512-sQ0Exvw6ccJ6ioZzPui/xPCWfHp/ogGskjbC/w4tjTZEE7Lwu+nDyt+QNZwC0rjRAu0FuZOGFsEc4JyWApez1w==, tarball: file:projects/contact-resources.tgz}
id: file:projects/contact-resources.tgz
name: '@rush-temp/contact-resources'
version: 0.0.0
@ -27678,7 +27695,7 @@ packages:
dev: false
file:projects/import-tool.tgz:
resolution: {integrity: sha512-8ZQpX7QgWZYBsG/Q307gT9dkAHebML7MeKTbOFsDRCcmj4lddBknHeP2m4LH2ZP7xk8dBuvnKR6SY0HwesLOrg==, tarball: file:projects/import-tool.tgz}
resolution: {integrity: sha512-QBo/RgAGnie95pESqQNJUQSCpQi1rEpXqZz1G1zZMfhAvisZtW2XutmaGMS1oDu2ZB05pk8WOO8x6bfdc+keZg==, tarball: file:projects/import-tool.tgz}
name: '@rush-temp/import-tool'
version: 0.0.0
dependencies:
@ -28289,7 +28306,7 @@ packages:
dev: false
file:projects/model-ai-bot.tgz:
resolution: {integrity: sha512-6ekOX88mYJEa+Lb+afb39noLVKRq935cP1EfVu9aqV5xbhFt6f1jKiDNz6eLtoR4zb/P8tBkFLfnu59rYMcIoA==, tarball: file:projects/model-ai-bot.tgz}
resolution: {integrity: sha512-tdvrfRa0PZZCWrUq5QqiZi4Bex97OgR7tMHVLMUJhhg7lJOnR9nyjFKn+X0lEI79pi0sllds53Ksdmi5Kd+OlQ==, tarball: file:projects/model-ai-bot.tgz}
name: '@rush-temp/model-ai-bot'
version: 0.0.0
dependencies:
@ -28348,7 +28365,7 @@ packages:
dev: false
file:projects/model-attachment.tgz:
resolution: {integrity: sha512-l6ido0KZWoQdDjZCYPzyauy2JZk04kXh48IpVSb4t4UwPfRXQKdKNZFecJxEyIkXW5T2uFYsWSpg+w7jYx85hw==, tarball: file:projects/model-attachment.tgz}
resolution: {integrity: sha512-DL/rIDjQ6d9r5gmpgzyLRkhlNNXE/3f0R5Ov5ZjvN4i6ghQSO5oeRW5qzm4MA3GtbIi6w8WOj8bSqJUW5hIsaw==, tarball: file:projects/model-attachment.tgz}
name: '@rush-temp/model-attachment'
version: 0.0.0
dependencies:
@ -28443,7 +28460,7 @@ packages:
dev: false
file:projects/model-contact.tgz:
resolution: {integrity: sha512-9JJBL0yu2LgUDzo51X9QPO+RyMeekvbXSIozSXKQR1ju3mYZoTlxsLPkqwh4qWYfUNYQyKCmyBtP7GlYsw27qw==, tarball: file:projects/model-contact.tgz}
resolution: {integrity: sha512-xIr8DSFUT2GSZ/4VvDc1zrlab+WhjCCM2tN/TNBEGroVUL2QW0/3VqODWs0UorvniaVWVoQNAj13cPZpE7yEfw==, tarball: file:projects/model-contact.tgz}
name: '@rush-temp/model-contact'
version: 0.0.0
dependencies:
@ -28520,7 +28537,7 @@ packages:
dev: false
file:projects/model-document.tgz:
resolution: {integrity: sha512-aQ1dqQdlY2Lc/HpchhCuHa3+9hqLhLA/I1OyVFBd1ap+qHLlLo5PyNnQE/laSmgW/3ULKXMG1xm3jRcmTT4VdA==, tarball: file:projects/model-document.tgz}
resolution: {integrity: sha512-tSr57oIXY1fECAB/axaDBJLSh/RVC4BXacjVHQ4wx3y+buoNngZoX9kpJsbNxEjCpW8yyhWwO1+sseyBi9RJdg==, tarball: file:projects/model-document.tgz}
name: '@rush-temp/model-document'
version: 0.0.0
dependencies:
@ -29679,7 +29696,7 @@ packages:
dev: false
file:projects/model-workbench.tgz:
resolution: {integrity: sha512-z/AtGaisKD57xttmNL8GsaX8ZvJ/LNqzZql5Kw9SDB1YKJIkICPGaT2WP+Os6mEd0B5dUHdrrfyxbVbXxPLyMA==, tarball: file:projects/model-workbench.tgz}
resolution: {integrity: sha512-V2NutYIJW4PcOf9i3vSpV5znaXD8SkItzvSnacTmbGWDjBkp7/pa8M5xFfoqoncMaGYerLAnsSlaxxw2k6i+TQ==, tarball: file:projects/model-workbench.tgz}
name: '@rush-temp/model-workbench'
version: 0.0.0
dependencies:
@ -30174,7 +30191,7 @@ packages:
dev: false
file:projects/pod-ai-bot.tgz(bufferutil@4.0.8)(utf-8-validate@6.0.4)(zod@3.23.8):
resolution: {integrity: sha512-5UmhFvpzsbI/QsMVitLsuANDxxsBo0me4HqpGVbAdMEUhTwaa1MvbCWCsWN8TQFlrEsRXv6iiv3ysiHi7LaWmA==, tarball: file:projects/pod-ai-bot.tgz}
resolution: {integrity: sha512-86BRJHqw7YBa4uTCvjyITwGUenWTJ6iSwZHZAI9Tf3gotChn1AhfK0HVVgGVQE+TGmW5R+oLx8s4NBMGBiZx1A==, tarball: file:projects/pod-ai-bot.tgz}
id: file:projects/pod-ai-bot.tgz
name: '@rush-temp/pod-ai-bot'
version: 0.0.0
@ -31463,17 +31480,18 @@ packages:
dev: false
file:projects/qms-tests-sanity.tgz:
resolution: {integrity: sha512-2NJnLTGNRdrMXybXslRQNNCyyDLmsA069UyXn8uBG/WQaMHzr9rTXvtRpltXSfgCn+WAc8VidyT68O6J8RAPQA==, tarball: file:projects/qms-tests-sanity.tgz}
resolution: {integrity: sha512-WH2sJcYUwJBzqHng4F/ceE1IkB4XD5HhfdsuSBgCSVD5jsqm+V39F0+AFmLhgQsJuvwd6D2rM/RaCE1hHmGxPw==, tarball: file:projects/qms-tests-sanity.tgz}
name: '@rush-temp/qms-tests-sanity'
version: 0.0.0
dependencies:
'@faker-js/faker': 8.4.1
'@playwright/test': 1.41.2
'@playwright/test': 1.47.2
'@types/jest': 29.5.12
'@types/node': 20.11.19
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3)
allure-playwright: 2.12.2
allure-js-commons: 3.0.4(allure-playwright@3.0.4)
allure-playwright: 3.0.4(@playwright/test@1.47.2)
cross-env: 7.0.3
dotenv: 16.0.3
eslint: 8.56.0
@ -35014,17 +35032,18 @@ packages:
dev: false
file:projects/tests-sanity.tgz:
resolution: {integrity: sha512-w1P9UqT2V0jsmryhTVIu4kmS0zK+Sb7rMuJiJMdgYoXknh1eSjImVEcZgScK2O/ujQSBTlgEla6YFnuxaIbMTQ==, tarball: file:projects/tests-sanity.tgz}
resolution: {integrity: sha512-Ii9d6GDonR1QAp1S1uBqI6QdL7y/Xm3PC7W/HkwUtv8QTH1/gEslKOo6dXE7jxE1rHJigMWiy3ZP1+PHLFnuhg==, tarball: file:projects/tests-sanity.tgz}
name: '@rush-temp/tests-sanity'
version: 0.0.0
dependencies:
'@faker-js/faker': 8.4.1
'@playwright/test': 1.41.2
'@playwright/test': 1.47.2
'@types/jest': 29.5.12
'@types/node': 20.11.19
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3)
'@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3)
allure-playwright: 2.12.2
allure-js-commons: 3.0.4(allure-playwright@3.0.4)
allure-playwright: 3.0.4(@playwright/test@1.47.2)
cross-env: 7.0.3
dotenv: 16.0.3
eslint: 8.56.0

View File

@ -85,6 +85,25 @@ async function loadTranslationsForComponent (plugin: Plugin, locale: string): Pr
}
}
function getCachedTranslation (id: _IdInfo, locale: string): IntlString | Status | undefined {
const localtTanslations = translations.get(locale)
if (localtTanslations === undefined) {
return undefined
}
const messages = localtTanslations.get(id.component)
if (messages === undefined) {
return undefined
}
if (messages instanceof Status) {
return messages
}
if (id.kind !== undefined) {
if ((messages[id.kind] as Record<string, IntlString>)?.[id.name] !== undefined) {
return (messages[id.kind] as Record<string, IntlString>)?.[id.name]
}
}
}
async function getTranslation (id: _IdInfo, locale: string): Promise<IntlString | Status | undefined> {
try {
const localtTanslations = translations.get(locale) ?? new Map<Plugin, Messages | Status<any>>()
@ -152,7 +171,7 @@ export async function translate<P extends Record<string, any>> (
if (id.component === _EmbeddedId) {
return id.name
}
const translation = (await getTranslation(id, locale)) ?? message
const translation = getCachedTranslation(id, locale) ?? (await getTranslation(id, locale)) ?? message
if (translation instanceof Status) {
localCache.set(message, translation)
return message
@ -162,9 +181,66 @@ export async function translate<P extends Record<string, any>> (
return compiled.format(params)
} catch (err) {
const status = unknownError(err)
await setPlatformStatus(status)
void setPlatformStatus(status)
localCache.set(message, status)
return message
}
}
}
/**
* Will do a translation in case language file already in cache, a translate is called and Promise is returned overwise
*/
export function translateCB<P extends Record<string, any>> (
message: IntlString<P>,
params: P,
language: string | undefined,
resolve: (value: string) => void
): void {
const locale = language ?? getMetadata(platform.metadata.locale) ?? 'en'
const localCache = cache.get(locale) ?? new Map<IntlString, IntlMessageFormat | Status>()
if (!cache.has(locale)) {
cache.set(locale, localCache)
}
const compiled = localCache.get(message)
if (compiled !== undefined) {
if (compiled instanceof Status) {
resolve(message)
return
}
resolve(compiled.format(params))
} else {
let id: _IdInfo
try {
id = _parseId(message)
if (id.component === _EmbeddedId) {
resolve(id.name)
return
}
} catch (err) {
const status = unknownError(err)
void setPlatformStatus(status)
localCache.set(message, status)
resolve(message)
return
}
const translation = getCachedTranslation(id, locale)
if (translation === undefined || translation instanceof Status) {
void translate(message, params, language)
.then((res) => {
resolve(res)
})
.catch((err) => {
const status = unknownError(err)
void setPlatformStatus(status)
localCache.set(message, status)
resolve(message)
})
return
}
const compiled = new IntlMessageFormat(translation, locale, undefined, { ignoreTag: true })
localCache.set(message, compiled)
resolve(compiled.format(params))
}
}

View File

@ -70,9 +70,9 @@ function getLocation (plugin: Plugin): PluginLoader<Resources> {
return location
}
const loading = new Map<Plugin, Promise<Resources>>()
const loading = new Map<Plugin, Resources | Promise<Resources>>()
async function loadPlugin (id: Plugin): Promise<Resources> {
function loadPlugin (id: Plugin): Resources | Promise<Resources> {
let pluginLoader = loading.get(id)
if (pluginLoader === undefined) {
const status = new Status(Severity.INFO, platform.status.LoadingPlugin, {
@ -99,7 +99,7 @@ async function loadPlugin (id: Plugin): Promise<Resources> {
)
loading.set(id, pluginLoader)
}
return await pluginLoader
return pluginLoader
}
const cachedResource = new Map<string, any>()
@ -115,8 +115,12 @@ export async function getResource<T> (resource: Resource<T>): Promise<T> {
return cached
}
const info = _parseId(resource)
const resources = loading.get(info.component) ?? loadPlugin(info.component)
const value = (await resources)[info.kind]?.[info.name]
let resources = loading.get(info.component) ?? loadPlugin(info.component)
if (resources instanceof Promise) {
resources = await resources
loading.set(info.component, resources)
}
const value = resources[info.kind]?.[info.name]
if (value === undefined) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.ResourceNotFound, { resource }))
}
@ -124,6 +128,15 @@ export async function getResource<T> (resource: Resource<T>): Promise<T> {
return value
}
/**
* @public
* @param resource -
* @returns
*/
export function getResourceP<T> (resource: Resource<T>): T | Promise<T> {
return cachedResource.get(resource) ?? getResource(resource)
}
/**
* @public
*/

View File

@ -25,7 +25,11 @@
{#if node}
{@const marks = node.marks ?? []}
<NodeMarks {marks}>
{#if marks.length > 0}
<NodeMarks {marks}>
<NodeContent {node} {preview} />
</NodeMarks>
{:else}
<NodeContent {node} {preview} />
</NodeMarks>
{/if}
{/if}

View File

@ -16,9 +16,9 @@
import { Class, Doc, Ref } from '@hcengineering/core'
import { AttrValue, MarkupNode, MarkupNodeType } from '@hcengineering/text'
import MarkupNodes from './Nodes.svelte'
import CodeBlockNode from './CodeBlockNode.svelte'
import ObjectNode from './ObjectNode.svelte'
import Node from './Node.svelte'
export let node: MarkupNode
export let preview = false
@ -52,16 +52,28 @@
{@const nodes = node.content ?? []}
{#if node.type === MarkupNodeType.doc}
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
{:else if node.type === MarkupNodeType.text}
{node.text}
{:else if node.type === MarkupNodeType.paragraph}
<p class="p-inline contrast" class:overflow-label={preview}>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</p>
{:else if node.type === MarkupNodeType.blockquote}
<blockquote class="proseBlockQuote" style:margin={preview ? '0' : null}>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</blockquote>
{:else if node.type === MarkupNodeType.horizontal_rule}
<hr />
@ -69,7 +81,11 @@
{@const level = toNumber(node.attrs?.level) ?? 1}
{@const element = `h${level}`}
<svelte:element this={element}>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</svelte:element>
{:else if node.type === MarkupNodeType.code_block}
<CodeBlockNode {node} {preview} />
@ -88,22 +104,36 @@
{#if objectClass !== undefined && objectId !== undefined}
<ObjectNode _id={toRef(objectId)} _class={toClassRef(objectClass)} title={objectLabel} />
{:else}
<MarkupNodes {nodes} {preview} />
{:else if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
{:else if node.type === MarkupNodeType.hard_break}
<br />
{:else if node.type === MarkupNodeType.ordered_list}
<ol style:margin={preview ? '0' : null}>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</ol>
{:else if node.type === MarkupNodeType.bullet_list}
<ul style:margin={preview ? '0' : null}>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</ul>
{:else if node.type === MarkupNodeType.list_item}
<li>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</li>
{:else if node.type === MarkupNodeType.taskList}
<!-- TODO not implemented -->
@ -111,33 +141,57 @@
<!-- TODO not implemented -->
{:else if node.type === MarkupNodeType.subLink}
<sub>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</sub>
{:else if node.type === MarkupNodeType.table}
<table class="proseTable">
<tbody>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</tbody>
</table>
{:else if node.type === MarkupNodeType.table_row}
<tr>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</tr>
{:else if node.type === MarkupNodeType.table_cell}
{@const colspan = toNumber(attrs.colspan)}
{@const rowspan = toNumber(attrs.rowspan)}
<td {colspan} {rowspan}>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</td>
{:else if node.type === MarkupNodeType.table_header}
{@const colspan = toNumber(attrs.colspan)}
{@const rowspan = toNumber(attrs.rowspan)}
<th {colspan} {rowspan}>
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
</th>
{:else}
unknown node: "{node.type}"
<MarkupNodes {nodes} {preview} />
{#if nodes.length > 0}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}
{/if}
{/if}

View File

@ -1,27 +0,0 @@
<!--
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { MarkupNode } from '@hcengineering/text'
import Node from './Node.svelte'
export let nodes: MarkupNode[]
export let preview = false
</script>
{#if nodes}
{#each nodes as node}
<Node {node} {preview} />
{/each}
{/if}

View File

@ -13,7 +13,7 @@
// limitations under the License.
-->
<script lang="ts">
import { getResource } from '@hcengineering/platform'
import { getResource, getResourceP } from '@hcengineering/platform'
import { deepEqual } from 'fast-equals'
import { SvelteComponent } from 'svelte'
import type { AnyComponent, AnySvelteComponent } from '../types'
@ -40,23 +40,56 @@
_props = props
}
$: component =
_is != null && typeof _is === 'string'
? getResource<any>(_is)
: _is == null
? Promise.reject(new Error('is not defined'))
: Promise.resolve(_is)
let Ctor: any
let loading = false
let error: any
let counter = 0
function updateComponent (_is: AnyComponent | AnySvelteComponent): void {
const current = ++counter
if (_is == null) {
Ctor = undefined
error = new Error('is not defined')
return
}
if (typeof _is === 'string') {
const component = getResourceP<any>(_is)
if (component instanceof Promise) {
loading = true
Ctor = undefined
void component
.then((res) => {
if (current === counter) {
Ctor = res
loading = false
}
})
.catch((err) => {
if (current === counter) {
error = err
}
})
} else {
Ctor = component
}
} else {
Ctor = _is
}
}
$: updateComponent(_is)
</script>
{#if _is}
{#await component}
{#if _is != null}
{#if loading}
{#if showLoading}
<Loading {shrink} />
{/if}
{:then Ctor}
<ErrorBoundary>
{:else if Ctor != null}
<ErrorBoundary bind:error>
{#if $$slots.default !== undefined}
<Ctor
<svelte:component
this={Ctor}
bind:this={innerRef}
{..._props}
{inline}
@ -72,9 +105,10 @@
on:submit
>
<slot />
</Ctor>
</svelte:component>
{:else}
<Ctor
<svelte:component
this={Ctor}
bind:this={innerRef}
{..._props}
{inline}
@ -91,10 +125,10 @@
/>
{/if}
</ErrorBoundary>
{:catch err}
<pre style="max-height: 140px; overflow: auto;">
<ErrorPresenter error={err} />
</pre>
<!-- <Icon icon={ui.icon.Error} size="32" /> -->
{/await}
{/if}
{/if}
{#if error != null}
<pre style="max-height: 140px; overflow: auto;">
<ErrorPresenter {error} />
</pre>
{/if}

View File

@ -14,14 +14,14 @@
-->
<script lang="ts">
import type { Asset, IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
import { createEventDispatcher, onMount } from 'svelte'
import { deviceOptionsStore, resizeObserver } from '..'
import plugin from '../plugin'
import type { AnySvelteComponent, ListItem } from '../types'
import Icon from './Icon.svelte'
import ListView from './ListView.svelte'
import { themeStore } from '@hcengineering/theme'
export let icon: Asset | AnySvelteComponent
export let placeholder: IntlString = plugin.string.SearchDots
@ -31,7 +31,7 @@
let search: string = ''
let phTranslate: string = ''
$: if (placeholder) {
translate(placeholder, {}, $themeStore.language).then((res) => {
translateCB(placeholder, {}, $themeStore.language, (res) => {
phTranslate = res
})
}
@ -121,6 +121,7 @@
</div>
</div>
</div>
>
<style lang="scss">
.img {

View File

@ -14,14 +14,14 @@
-->
<script lang="ts">
import type { IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
import { createEventDispatcher, onMount } from 'svelte'
import { registerFocus } from '../focus'
import plugin from '../plugin'
import type { EditStyle } from '../types'
import Label from './Label.svelte'
import { floorFractionDigits } from '../utils'
import { themeStore } from '@hcengineering/theme'
import Label from './Label.svelte'
export let id: string | undefined = undefined
export let label: IntlString | undefined = undefined
@ -56,7 +56,7 @@
value = floorFractionDigits(Number(value), maxDigitsAfterPoint)
}
}
$: void translate(placeholder, placeholderParam ?? {}, $themeStore.language).then((res) => {
$: translateCB(placeholder, placeholderParam ?? {}, $themeStore.language, (res) => {
phTranslate = res
})

View File

@ -14,14 +14,14 @@
-->
<script lang="ts">
import type { Asset, IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
import { createEventDispatcher, ComponentType } from 'svelte'
import { ComponentType, createEventDispatcher } from 'svelte'
import plugin from '../plugin'
import type { AnySvelteComponent } from '../types'
import Icon from './Icon.svelte'
import Button from './Button.svelte'
import Icon from './Icon.svelte'
import IconClose from './icons/Close.svelte'
import Spinner from './Spinner.svelte'
@ -44,7 +44,7 @@
autoFocus = false
}
$: void translate(placeholder, placeholderParam ?? {}, $themeStore.language).then((res) => {
$: translateCB(placeholder, placeholderParam ?? {}, $themeStore.language, (res) => {
phTranslate = res
})
$: if (textHTML !== undefined) {
@ -87,6 +87,7 @@
{/if}
</div>
</div>
>
<style lang="scss">
.editbox {

View File

@ -14,7 +14,7 @@
-->
<script lang="ts">
import type { IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
export let label: IntlString
@ -23,13 +23,9 @@
let _value: string | undefined
$: if (label !== undefined) {
translate(label, params ?? {}, $themeStore.language)
.then((r) => {
_value = r
})
.catch((err) => {
console.error(err)
})
translateCB(label, params ?? {}, $themeStore.language, (r) => {
_value = r
})
} else {
_value = label
}

View File

@ -15,15 +15,17 @@
<script lang="ts">
// This component converts all URLs from the provided string or IntlString to Links.
import { IntlString, translate } from '@hcengineering/platform'
import { replaceURLs } from '../utils'
import { IntlString, translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
import { replaceURLs } from '../utils'
export let text: string | undefined = undefined
export let label: IntlString | undefined = undefined
export let params: Readonly<Record<string, any>> = {}
$: label && translate(label, params, $themeStore.language).then((result) => (text = result))
$: if (label) {
translateCB(label, params, $themeStore.language, (result) => (text = result))
}
</script>
{#if text}

View File

@ -8,25 +8,30 @@
export let expansion: 'stretch' | 'default' = 'default'
export let padding: string | undefined = undefined
$: modeList = props.config.map((c) => {
return {
id: c[0],
labelIntl: c[1],
labelParams: c[2],
action: () => {
props.onChange(c[0])
}
}
})
$: modeList =
props.config != null
? props.config.map((c) => {
return {
id: c[0],
labelIntl: c[1],
labelParams: c[2],
action: () => {
props.onChange(c[0])
}
}
})
: []
</script>
<Switcher
name={'modeSelector'}
items={modeList}
selected={props.mode}
{kind}
{onlyIcons}
on:select={(result) => {
if (result.detail !== undefined && result.detail.action) result.detail.action()
}}
/>
{#if modeList.length > 0}
<Switcher
name={'modeSelector'}
items={modeList}
selected={props.mode}
{kind}
{onlyIcons}
on:select={(result) => {
if (result.detail !== undefined && result.detail.action) result.detail.action()
}}
/>
{/if}

View File

@ -4,11 +4,11 @@
// Licensed under the Eclipse Public License v2.0 (SPDX: EPL-2.0).
//
import { IntlString, translateCB } from '@hcengineering/platform'
import { createEventDispatcher, onMount } from 'svelte'
import { IntlString, translate } from '@hcengineering/platform'
import { themeStore } from '..'
import { registerFocus } from '../focus'
import Label from './Label.svelte'
import { themeStore } from '..'
export let label: IntlString
export let value: string | undefined = undefined
@ -28,7 +28,7 @@
$: maxlength = limit === 0 ? null : limit
let placeholderStr: string = ''
$: ph = translate(label, {}, $themeStore.language).then((r) => {
$: translateCB(label, {}, $themeStore.language, (r) => {
placeholderStr = r
})
$: labeled = kind === 'default' && size === 'large'

View File

@ -14,16 +14,16 @@
-->
<script lang="ts">
import type { IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
import { afterUpdate, createEventDispatcher, onMount } from 'svelte'
import { registerFocus } from '../focus'
import plugin from '../plugin'
import { resizeObserver } from '../resize'
import { floorFractionDigits } from '../utils'
import Button from './Button.svelte'
import DownOutline from './icons/DownOutline.svelte'
import UpOutline from './icons/UpOutline.svelte'
import Button from './Button.svelte'
export let maxWidth: string | undefined = undefined
export let value: number = 0
@ -58,7 +58,7 @@
if (minValue !== undefined && value < minValue) value = minValue
}
$: style = `max-width: ${maxWidth || (parentWidth ? `${parentWidth}px` : 'max-content')};`
$: translate(placeholder, placeholderParam ?? {}, $themeStore.language).then((res) => {
$: translateCB(placeholder, placeholderParam ?? {}, $themeStore.language, (res) => {
phTranslate = res
})
@ -157,6 +157,7 @@
</div>
</div>
</div>
>
<style lang="scss">
.editbox-container {

View File

@ -13,13 +13,13 @@
// limitations under the License.
-->
<script lang="ts">
import { afterUpdate, onMount } from 'svelte'
import type { IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
import { afterUpdate, onMount } from 'svelte'
import { DelayedCaller } from '../utils'
import ui from '../plugin'
import { DelayedCaller } from '../utils'
export let value: string | undefined = undefined
export let placeholder: IntlString = ui.string.TypeHere
@ -29,7 +29,7 @@
let input: HTMLTextAreaElement
let phTranslate: string = ''
$: void translate(placeholder, placeholderParam ?? {}, $themeStore.language).then((res) => {
$: translateCB(placeholder, placeholderParam ?? {}, $themeStore.language, (res) => {
phTranslate = res
})
@ -73,6 +73,7 @@
on:keypress
on:blur
/>
>
<style lang="scss">
.root {

View File

@ -13,13 +13,13 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher, onDestroy } from 'svelte'
import type { IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
import IconSearch from './icons/Search.svelte'
import IconClose from './icons/Close.svelte'
import { createEventDispatcher, onDestroy } from 'svelte'
import plugin from '../plugin'
import IconClose from './icons/Close.svelte'
import IconSearch from './icons/Search.svelte'
export let value: string | undefined = undefined
export let placeholder: IntlString = plugin.string.Search
@ -29,7 +29,7 @@
let input: HTMLInputElement
let phTranslate: string = ''
$: void translate(placeholder, placeholderParam ?? {}, $themeStore.language).then((res) => {
$: translateCB(placeholder, placeholderParam ?? {}, $themeStore.language, (res) => {
phTranslate = res
})
@ -86,6 +86,7 @@
<IconClose size={'small'} />
</button>
</label>
>
<style lang="scss">
.searchInput-wrapper {

View File

@ -14,10 +14,10 @@
-->
<script lang="ts">
import type { IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
import plugin from '../plugin'
import Label from './Label.svelte'
import { themeStore } from '@hcengineering/theme'
export let label: IntlString | undefined = undefined
export let width: string | undefined = undefined
@ -32,7 +32,7 @@
let input: HTMLTextAreaElement
let phTranslate: string = ''
$: translate(placeholder, placeholderParam ?? {}, $themeStore.language).then((res) => {
$: translateCB(placeholder, placeholderParam ?? {}, $themeStore.language, (res) => {
phTranslate = res
})
@ -55,6 +55,7 @@
on:blur
/>
</div>
>
<style lang="scss">
.textarea {

View File

@ -14,12 +14,12 @@
// limitations under the License.
-->
<script lang="ts">
import { translate } from '@hcengineering/platform'
import { DAY, HOUR, MINUTE, MONTH, YEAR } from '../types'
import ui from '../plugin'
import { tooltip } from '../tooltips'
import { translateCB } from '@hcengineering/platform'
import { themeStore } from '@hcengineering/theme'
import { ticker } from '..'
import ui from '../plugin'
import { tooltip } from '../tooltips'
import { DAY, HOUR, MINUTE, MONTH, YEAR } from '../types'
export let value: number | undefined
export let kind: 'no-border' | 'list' = 'no-border'
@ -37,19 +37,29 @@
return (endYear - startYear) * 12 + (endMonth - startMonth)
}
async function formatTime (now: number, value: number) {
function formatTime (now: number, value: number): void {
let passed = now - value
if (passed < 0) passed = 0
if (passed < HOUR) {
time = await translate(ui.string.MinutesAgo, { minutes: Math.floor(passed / MINUTE) }, $themeStore.language)
translateCB(ui.string.MinutesAgo, { minutes: Math.floor(passed / MINUTE) }, $themeStore.language, (res) => {
time = res
})
} else if (passed < DAY) {
time = await translate(ui.string.HoursAgo, { hours: Math.floor(passed / HOUR) }, $themeStore.language)
translateCB(ui.string.HoursAgo, { hours: Math.floor(passed / HOUR) }, $themeStore.language, (res) => {
time = res
})
} else if (passed < MONTH) {
time = await translate(ui.string.DaysAgo, { days: Math.floor(passed / DAY) }, $themeStore.language)
translateCB(ui.string.DaysAgo, { days: Math.floor(passed / DAY) }, $themeStore.language, (res) => {
time = res
})
} else if (passed < YEAR) {
time = await translate(ui.string.MonthsAgo, { months: calculateMonthsPassed(now, value) }, $themeStore.language)
translateCB(ui.string.MonthsAgo, { months: calculateMonthsPassed(now, value) }, $themeStore.language, (res) => {
time = res
})
} else {
time = await translate(ui.string.YearsAgo, { years: Math.floor(passed / YEAR) }, $themeStore.language)
translateCB(ui.string.YearsAgo, { years: Math.floor(passed / YEAR) }, $themeStore.language, (res) => {
time = res
})
}
}
@ -74,3 +84,4 @@
>
{time}
</span>
span>

View File

@ -21,6 +21,7 @@ export default class errorBoundary extends ErrorComponent {
try {
return x(...args)
} catch (e) {
console.error(e)
error = e
}
})

View File

@ -22,13 +22,13 @@
personAccountByIdStore,
personByIdStore
} from '@hcengineering/contact-resources'
import { Action } from '@hcengineering/ui'
import { Ref } from '@hcengineering/core'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { HTMLViewer } from '@hcengineering/presentation'
import { Action, themeStore } from '@hcengineering/ui'
import ActivityMessageTemplate from '../activity-message/ActivityMessageTemplate.svelte'
import ActivityMessageHeader from '../activity-message/ActivityMessageHeader.svelte'
import ActivityMessageTemplate from '../activity-message/ActivityMessageTemplate.svelte'
export let value: ActivityInfoMessage
export let showNotify: boolean = false
@ -52,13 +52,9 @@
let content = ''
$: void translate(value.message, value.props)
.then((message) => {
content = message
})
.catch((err) => {
content = JSON.stringify(err, null, 2)
})
$: translateCB(value.message, value.props, $themeStore.language, (message) => {
content = message
})
</script>
<ActivityMessageTemplate

View File

@ -16,7 +16,7 @@
import contact, { Person, PersonAccount } from '@hcengineering/contact'
import { CreateGuest, personAccountByIdStore } from '@hcengineering/contact-resources'
import { IdMap, Ref } from '@hcengineering/core'
import { IntlString, translate } from '@hcengineering/platform'
import { IntlString, translateCB } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import setting, { Integration } from '@hcengineering/setting'
import { themeStore } from '@hcengineering/theme'
@ -44,7 +44,7 @@
let parentWidth: number | undefined
$: style = `max-width: ${maxWidth || (parentWidth ? `${parentWidth}px` : 'max-content')};`
$: translate(placeholder, {}, $themeStore.language).then((res) => {
$: translateCB(placeholder, {}, $themeStore.language, (res) => {
phTranslate = res
})

View File

@ -635,15 +635,23 @@
loadMore()
}
let timer: any
function saveScrollPosition (): void {
if (!scrollElement) {
return
}
const { offsetHeight, scrollHeight, scrollTop } = scrollElement
prevScrollHeight = scrollElement.scrollHeight
prevScrollHeight = scrollHeight
isScrollAtBottom = scrollHeight <= Math.ceil(scrollTop + offsetHeight)
clearTimeout(timer)
setTimeout(() => {
if (!scrollElement) {
return
}
const { offsetHeight, scrollHeight, scrollTop } = scrollElement
isScrollAtBottom = scrollHeight <= Math.ceil(scrollTop + offsetHeight)
}, 15)
}
beforeUpdate(() => {

View File

@ -495,7 +495,7 @@ class Connection implements ClientConnection {
}
}
private async sendRequest (data: {
private sendRequest (data: {
method: string
params: any[]
// If not defined, on reconnect with timeout, will retry automatically.
@ -505,7 +505,7 @@ class Connection implements ClientConnection {
measure?: (time: number, result: any, serverTime: number, queue: number, toRecieve: number) => void
allowReconnect?: boolean
}): Promise<any> {
return await this.ctx.newChild('send-request', {}).with(data.method, {}, async (ctx) => {
return this.ctx.newChild('send-request', {}).with(data.method, {}, async (ctx) => {
if (this.closed) {
throw new PlatformError(unknownError('connection closed'))
}
@ -530,7 +530,7 @@ class Connection implements ClientConnection {
await w
}
this.requests.set(id, promise)
const sendData = async (): Promise<void> => {
const sendData = (): void => {
if (this.websocket?.readyState === ClientSocketReadyState.OPEN) {
promise.startTime = Date.now()
@ -553,23 +553,25 @@ class Connection implements ClientConnection {
setTimeout(async () => {
// In case we don't have response yet.
if (this.requests.has(id) && ((await data.retry?.()) ?? true)) {
void sendData()
sendData()
}
}, 50)
}
}
void ctx.with('send-data', {}, () => sendData())
ctx.withSync('send-data', {}, () => {
sendData()
})
void ctx.with('broadcast-event', {}, () => broadcastEvent(client.event.NetworkRequests, this.requests.size))
return await promise.promise
})
}
async loadModel (last: Timestamp, hash?: string): Promise<Tx[] | LoadModelResponse> {
return await this.sendRequest({ method: 'loadModel', params: [last, hash] })
loadModel (last: Timestamp, hash?: string): Promise<Tx[] | LoadModelResponse> {
return this.sendRequest({ method: 'loadModel', params: [last, hash] })
}
async getAccount (): Promise<Account> {
return await this.sendRequest({ method: 'getAccount', params: [] })
getAccount (): Promise<Account> {
return this.sendRequest({ method: 'getAccount', params: [] })
}
async findAll<T extends Doc>(

View File

@ -16,7 +16,7 @@
import { Channel } from '@hcengineering/contact'
import { Data } from '@hcengineering/core'
import type { IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { copyTextToClipboard } from '@hcengineering/presentation'
import {
Button,
@ -32,8 +32,8 @@
showPopup,
themeStore
} from '@hcengineering/ui'
import { ContextMenu } from '@hcengineering/view-resources'
import view from '@hcengineering/view'
import { ContextMenu } from '@hcengineering/view-resources'
import { afterUpdate, createEventDispatcher, onMount } from 'svelte'
import plugin from '../plugin'
import IconCopy from './icons/Copy.svelte'
@ -47,10 +47,10 @@
const dispatch = createEventDispatcher()
let input: HTMLInputElement
let phTranslate: string
$: translate(placeholder, {}, $themeStore.language).then((tr) => (phTranslate = tr))
$: translateCB(placeholder, {}, $themeStore.language, (tr) => (phTranslate = tr))
let label: IntlString = plugin.string.CopyToClipboard
let lTranslate: string
$: translate(label, {}, $themeStore.language).then((tr) => (lTranslate = tr))
$: translateCB(label, {}, $themeStore.language, (tr) => (lTranslate = tr))
let show: boolean = false
const copyChannel = (): void => {

View File

@ -13,12 +13,12 @@
// limitations under the License.
-->
<script lang="ts">
import { Doc, Ref } from '@hcengineering/core'
import { Button, showPopup, eventToHTMLElement, themeStore } from '@hcengineering/ui'
import type { ButtonKind, ButtonSize } from '@hcengineering/ui'
import contact, { Employee } from '@hcengineering/contact'
import { Doc, Ref } from '@hcengineering/core'
import { IntlString, translateCB } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation'
import { IntlString, translate } from '@hcengineering/platform'
import type { ButtonKind, ButtonSize } from '@hcengineering/ui'
import { Button, eventToHTMLElement, showPopup, themeStore } from '@hcengineering/ui'
import UsersPopup from './UsersPopup.svelte'
export let value: Doc
@ -36,7 +36,7 @@
let buttonTitle = ''
$: members = retrieveMembers(value)
$: translate(intlTitle, {}, $themeStore.language).then((res) => {
$: translateCB(intlTitle, {}, $themeStore.language, (res) => {
buttonTitle = res
})

View File

@ -24,7 +24,7 @@
getCurrentAccount,
hasAccountRole
} from '@hcengineering/core'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import presentation, { getClient } from '@hcengineering/presentation'
import { ActionIcon, IconAdd, IconClose, Label, SearchEdit, showPopup, themeStore } from '@hcengineering/ui'
import AddMembersPopup from './AddMembersPopup.svelte'
@ -37,9 +37,7 @@
const hierarchy = client.getHierarchy()
$: label = hierarchy.getClass(space._class).label
let spaceClass = ''
$: {
translate(label, {}, $themeStore.language).then((p) => (spaceClass = p.toLowerCase()))
}
$: translateCB(label, {}, $themeStore.language, (p) => (spaceClass = p.toLowerCase()))
let search: string = ''
$: isSearch = search.trim().length
let members: Set<Ref<Person>> = new Set<Ref<Person>>()

View File

@ -15,7 +15,7 @@
//
-->
<script lang="ts">
import { IntlString, translate } from '@hcengineering/platform'
import { IntlString, translateCB } from '@hcengineering/platform'
import { registerFocus, themeStore } from '@hcengineering/ui'
import { onMount } from 'svelte'
@ -28,9 +28,11 @@
let input: HTMLInputElement
let placeholderTranslation = ''
async function updatePlaceholderTranslation (ph: IntlString | undefined) {
function updatePlaceholderTranslation (ph: IntlString | undefined): void {
if (ph) {
placeholderTranslation = await translate(ph, {}, $themeStore.language)
translateCB(ph, {}, $themeStore.language, (res) => {
placeholderTranslation = res
})
}
}

View File

@ -13,11 +13,12 @@
// limitations under the License.
-->
<script lang="ts">
import { Doc, Markup } from '@hcengineering/core'
import { IntlString, translate } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation'
import { CommonInboxNotification } from '@hcengineering/notification'
import { BasePreview } from '@hcengineering/activity-resources'
import { Doc, Markup } from '@hcengineering/core'
import { CommonInboxNotification } from '@hcengineering/notification'
import { IntlString, translateCB } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation'
import { themeStore } from '@hcengineering/ui'
export let value: CommonInboxNotification
@ -31,7 +32,9 @@
if (messageHtml !== undefined) {
content = messageHtml
} else if (message !== undefined) {
content = await translate(message, value.props)
translateCB(message, value.props, $themeStore.language, (res) => {
content = res
})
}
}

View File

@ -14,24 +14,23 @@
-->
<script lang="ts">
import core, { AnyAttribute, Class, DocumentUpdate, IndexKind, PropertyType, Ref, Type } from '@hcengineering/core'
import { getEmbeddedLabel, getResource, translate } from '@hcengineering/platform'
import { getEmbeddedLabel, getResource, translateCB } from '@hcengineering/platform'
import presentation, { getClient } from '@hcengineering/presentation'
import setting from '../plugin'
import {
AnyComponent,
ButtonIcon,
Component,
DropdownIntlItem,
DropdownLabelsIntl,
ModernEditbox,
Label,
themeStore,
Modal,
ButtonIcon,
IconDelete,
IconCopy
Label,
Modal,
ModernEditbox,
themeStore
} from '@hcengineering/ui'
import view from '@hcengineering/view-resources/src/plugin'
import { clearSettingsStore, settingsStore } from '../store'
import setting from '../plugin'
import { clearSettingsStore } from '../store'
export let attribute: AnyAttribute
export let exist: boolean
@ -46,7 +45,9 @@
const client = getClient()
const hierarchy = client.getHierarchy()
translate(attribute.label, {}, $themeStore.language).then((p) => (name = p))
translateCB(attribute.label, {}, $themeStore.language, (p) => {
name = p
})
async function save (): Promise<void> {
if (disabled) {

View File

@ -15,7 +15,7 @@
<script lang="ts">
import { Class, Doc, Ref } from '@hcengineering/core'
import type { IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import presentation, { createQuery } from '@hcengineering/presentation'
import { TagCategory, TagElement } from '@hcengineering/tags'
import {
@ -47,7 +47,7 @@
let phTranslate: string = ''
$: if (placeholder) {
translate(placeholder, {}, $themeStore.language).then((res) => {
translateCB(placeholder, {}, $themeStore.language, (res) => {
phTranslate = res
})
}

View File

@ -14,7 +14,7 @@
-->
<script lang="ts">
import type { AttachedDoc, Class, Collection, Doc, Ref } from '@hcengineering/core'
import { IntlString, translate } from '@hcengineering/platform'
import { IntlString, translateCB } from '@hcengineering/platform'
import { KeyedAttribute } from '@hcengineering/presentation'
import { TagElement, TagReference } from '@hcengineering/tags'
import type { ButtonKind, ButtonSize, TooltipAlignment } from '@hcengineering/ui'
@ -44,7 +44,7 @@
$: itemLabel = (key.attr.type as Collection<AttachedDoc>).itemLabel
$: void translate(itemLabel ?? key.attr.label, {}, $themeStore.language).then((v) => {
$: translateCB(itemLabel ?? key.attr.label, {}, $themeStore.language, (v) => {
keyLabel = v
})
@ -85,6 +85,11 @@
async function removeTag (id: Ref<TagReference>): Promise<void> {
dispatch('delete', id)
}
let countText = ''
$: translateCB(countLabel, { count: items.length }, $themeStore.language, (res) => {
countText = res
})
</script>
<Button
@ -103,9 +108,7 @@
<svelte:fragment slot="content">
{#if items.length > 0}
<span class="flex-row-center flex-nowrap overflow-label disabled">
{#await translate(countLabel, { count: items.length }, $themeStore.language) then text}
{text}
{/await}
{countText}
</span>
{/if}
</svelte:fragment>

View File

@ -22,7 +22,7 @@
type IdMap,
type Ref
} from '@hcengineering/core'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { createQuery, KeyedAttribute } from '@hcengineering/presentation'
import { TagElement, TagReference } from '@hcengineering/tags'
import {
@ -59,7 +59,7 @@
$: itemLabel = (key.attr.type as Collection<AttachedDoc>).itemLabel
$: translate(itemLabel ?? key.attr.label, {}, $themeStore.language).then((v) => {
$: translateCB(itemLabel ?? key.attr.label, {}, $themeStore.language, (v) => {
keyLabel = v
})

View File

@ -14,18 +14,18 @@
-->
<script lang="ts">
import { Class, Doc, DocumentQuery, FindOptions, Ref } from '@hcengineering/core'
import { Asset, IntlString, translate } from '@hcengineering/platform'
import { Asset, IntlString, translateCB } from '@hcengineering/platform'
import { createQuery } from '@hcengineering/presentation'
import { TagCategory, TagElement } from '@hcengineering/tags'
import {
AnySvelteComponent,
Button,
Breadcrumb,
Button,
Header,
IconAdd,
SearchInput,
showPopup,
IconAdd,
themeStore,
Header
themeStore
} from '@hcengineering/ui'
import { TableBrowser } from '@hcengineering/view-resources'
import tags from '../plugin'
@ -42,7 +42,7 @@
export let onTag: ((tag: TagElement) => void) | undefined = undefined
let keyTitle: string
$: translate(item, {}, $themeStore.language).then((t) => {
$: translateCB(item, {}, $themeStore.language, (t) => {
keyTitle = t.toLowerCase()
})

View File

@ -1,7 +1,7 @@
<script lang="ts">
import { translate } from '@hcengineering/platform'
import { areDatesEqual } from '@hcengineering/ui'
import { translateCB } from '@hcengineering/platform'
import { ToDo, WorkSlot } from '@hcengineering/time'
import { areDatesEqual, themeStore } from '@hcengineering/ui'
import timePlugin from '../plugin'
import { getNearest } from '../utils'
@ -12,22 +12,28 @@
$: near = getNearest(events)
async function getText (todo: ToDo, near: WorkSlot | undefined): Promise<void> {
function getText (todo: ToDo, near: WorkSlot | undefined): void {
const today = new Date()
const tomorrow = new Date(new Date().setDate(new Date().getDate() + 1))
const yesterday = new Date(new Date().setDate(new Date().getDate() - 1))
if (todo.doneOn != null) {
const day = new Date(todo.doneOn)
if (areDatesEqual(day, today)) {
str = await translate(timePlugin.string.Today, {})
translateCB(timePlugin.string.Today, {}, $themeStore.language, (res) => {
str = res
})
return
}
if (areDatesEqual(day, yesterday)) {
str = await translate(timePlugin.string.Yesterday, {})
translateCB(timePlugin.string.Yesterday, {}, $themeStore.language, (res) => {
str = res
})
return
}
if (areDatesEqual(day, tomorrow)) {
str = await translate(timePlugin.string.Tomorrow, {})
translateCB(timePlugin.string.Tomorrow, {}, $themeStore.language, (res) => {
str = res
})
return
}
str = new Date(todo.doneOn).toLocaleString('default', {
@ -49,20 +55,28 @@
})
const day = new Date(near.date)
if (areDatesEqual(day, today)) {
str = `${await translate(timePlugin.string.Today, {})} ${time}`
translateCB(timePlugin.string.Today, {}, $themeStore.language, (res) => {
str = `${res} ${time}`
})
return
}
if (areDatesEqual(day, yesterday)) {
str = `${await translate(timePlugin.string.Yesterday, {})} ${time}`
translateCB(timePlugin.string.Yesterday, {}, $themeStore.language, (res) => {
str = `${res} ${time}`
})
return
}
if (areDatesEqual(day, tomorrow)) {
str = `${await translate(timePlugin.string.Tomorrow, {})} ${time}`
translateCB(timePlugin.string.Tomorrow, {}, $themeStore.language, (res) => {
str = `${res} ${time}`
})
return
}
return
}
str = await translate(timePlugin.string.Inbox, {})
translateCB(timePlugin.string.Inbox, {}, $themeStore.language, (res) => {
str = res
})
}
let str = ''

View File

@ -14,7 +14,7 @@
-->
<script lang="ts">
import { WithLookup } from '@hcengineering/core'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { Component } from '@hcengineering/tracker'
import { Icon, themeStore } from '@hcengineering/ui'
import view from '@hcengineering/view'
@ -35,13 +35,9 @@
$: if (value !== undefined) {
label = value.label
} else {
translate(tracker.string.NoComponent, {}, $themeStore.language)
.then((r) => {
label = r
})
.catch((err) => {
console.error(err)
})
translateCB(tracker.string.NoComponent, {}, $themeStore.language, (r) => {
label = r
})
}
$: disabled = disabled || value === undefined
</script>

View File

@ -13,25 +13,35 @@
// limitations under the License.
-->
<script lang="ts">
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import ui, { DAY, HOUR, MINUTE, MONTH, YEAR, themeStore } from '@hcengineering/ui'
export let value: number
let time: string = ''
async function formatTime (passed: number) {
function formatTime (passed: number): void {
if (passed < 0) passed = 0
if (passed < HOUR) {
time = await translate(ui.string.Minutes, { minutes: Math.floor(passed / MINUTE) }, $themeStore.language)
translateCB(ui.string.Minutes, { minutes: Math.floor(passed / MINUTE) }, $themeStore.language, (res) => {
time = res
})
} else if (passed < DAY) {
time = await translate(ui.string.Hours, { hours: Math.floor(passed / HOUR) }, $themeStore.language)
translateCB(ui.string.Hours, { hours: Math.floor(passed / HOUR) }, $themeStore.language, (res) => {
time = res
})
} else if (passed < MONTH) {
time = await translate(ui.string.Days, { days: Math.floor(passed / DAY) }, $themeStore.language)
translateCB(ui.string.Days, { days: Math.floor(passed / DAY) }, $themeStore.language, (res) => {
time = res
})
} else if (passed < YEAR) {
time = await translate(ui.string.Months, { months: Math.floor(passed / MONTH) }, $themeStore.language)
translateCB(ui.string.Months, { months: Math.floor(passed / MONTH) }, $themeStore.language, (res) => {
time = res
})
} else {
time = await translate(ui.string.Years, { years: Math.floor(passed / YEAR) }, $themeStore.language)
translateCB(ui.string.Years, { years: Math.floor(passed / YEAR) }, $themeStore.language, (res) => {
time = res
})
}
}

View File

@ -1,13 +1,13 @@
<script lang="ts">
import { DocumentQuery, Ref, Space, WithLookup } from '@hcengineering/core'
import { IntlString, Asset, translate } from '@hcengineering/platform'
import { Asset, IntlString, translateCB } from '@hcengineering/platform'
import { ComponentExtensions } from '@hcengineering/presentation'
import { Issue, TrackerEvents } from '@hcengineering/tracker'
import { IModeSelector, themeStore } from '@hcengineering/ui'
import { ViewOptions, Viewlet } from '@hcengineering/view'
import { FilterBar, SpaceHeader, ViewletContentView, ViewletSettingButton } from '@hcengineering/view-resources'
import tracker from '../../plugin'
import CreateIssue from '../CreateIssue.svelte'
import { ComponentExtensions } from '@hcengineering/presentation'
export let space: Ref<Space> | undefined = undefined
export let query: DocumentQuery<Issue> = {}
@ -29,7 +29,7 @@
let resultQuery: DocumentQuery<Issue> = { ...searchQuery }
$: if (title) {
void translate(title, {}, $themeStore.language).then((res) => {
translateCB(title, {}, $themeStore.language, (res) => {
label = res
})
}

View File

@ -14,7 +14,7 @@
-->
<script lang="ts">
import { DocumentQuery, Ref, SortingOrder } from '@hcengineering/core'
import { IntlString, getEmbeddedLabel, translate } from '@hcengineering/platform'
import { IntlString, getEmbeddedLabel, translateCB } from '@hcengineering/platform'
import { createQuery } from '@hcengineering/presentation'
import { Milestone } from '@hcengineering/tracker'
import type { ButtonKind, ButtonSize, LabelAndProps, PopupResult } from '@hcengineering/ui'
@ -59,7 +59,7 @@
$: handleSelectedMilestoneIdUpdated(value, rawMilestones)
$: translate(tracker.string.Milestone, {}, $themeStore.language).then((result) => (defaultMilestoneLabel = result))
$: translateCB(tracker.string.Milestone, {}, $themeStore.language, (result) => (defaultMilestoneLabel = result))
const milestoneIcon = tracker.icon.Milestone
$: milestoneText = shouldShowLabel ? selectedMilestone?.label ?? defaultMilestoneLabel : undefined

View File

@ -18,13 +18,11 @@
Ref,
SearchResultDoc,
Tx,
TxBuilder,
TxWorkspaceEvent,
WithLookup,
WorkspaceEvent,
coreId
WorkspaceEvent
} from '@hcengineering/core'
import { getResource, translate } from '@hcengineering/platform'
import { getResource, translate, translateCB } from '@hcengineering/platform'
import {
ActionContext,
SearchResult,
@ -292,7 +290,7 @@
if (autoFocus) focus()
}
$: void translate(view.string.ActionPlaceholder, {}).then((res) => {
$: translateCB(view.string.ActionPlaceholder, {}, $themeStore.language, (res) => {
phTraslate = res
})
let timer: any

View File

@ -14,7 +14,7 @@
-->
<script lang="ts">
import type { IntlString } from '@hcengineering/platform'
import { translate } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import { copyTextToClipboard } from '@hcengineering/presentation'
import { Button, IconArrowRight, IconBlueCheck, IconClose, IconCopy, Label, themeStore } from '@hcengineering/ui'
import { createEventDispatcher, onMount } from 'svelte'
@ -27,7 +27,7 @@
const dispatch = createEventDispatcher()
let input: HTMLInputElement
let phTranslate: string
$: translate(placeholder, {}, $themeStore.language).then((tr) => (phTranslate = tr))
$: translateCB(placeholder, {}, $themeStore.language, (tr) => (phTranslate = tr))
onMount(() => {
if (input) input.focus()

View File

@ -14,13 +14,13 @@
-->
<script lang="ts">
import { Class, Doc, Ref } from '@hcengineering/core'
import { getResource, translateCB } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import { AnyComponent, LabelAndProps, themeStore, tooltip } from '@hcengineering/ui'
import view from '@hcengineering/view'
import { getResource, translate } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import DocNavLink from './DocNavLink.svelte'
import { getDocIdentifier } from '../utils'
import DocNavLink from './DocNavLink.svelte'
export let _id: Ref<Doc> | undefined = undefined
export let _class: Ref<Class<Doc>> | undefined = undefined
@ -81,7 +81,13 @@
async function updateDocLabel (doc?: Doc, _class?: Ref<Class<Doc>>): Promise<void> {
const resultClass = doc?._class ?? _class
docLabel = resultClass ? await translate(hierarchy.getClass(resultClass).label, {}, $themeStore.language) : ''
if (resultClass != null) {
translateCB(hierarchy.getClass(resultClass).label, {}, $themeStore.language, (res) => {
docLabel = res
})
} else {
docLabel = ''
}
}
async function updateDocTitle (doc: Doc | undefined): Promise<void> {

View File

@ -5,16 +5,16 @@
-->
<script lang="ts">
import { Class, Doc, DocumentQuery, Ref, Space, WithLookup } from '@hcengineering/core'
import { translate } from '@hcengineering/platform'
import type { IntlString, Asset } from '@hcengineering/platform'
import type { Asset, IntlString } from '@hcengineering/platform'
import { translateCB } from '@hcengineering/platform'
import {
IModeSelector,
SearchInput,
ModeSelector,
themeStore,
Header,
Breadcrumb,
HeaderAdaptive
Header,
HeaderAdaptive,
IModeSelector,
ModeSelector,
SearchInput,
themeStore
} from '@hcengineering/ui'
import { ViewOptions, Viewlet, ViewletPreference } from '@hcengineering/view'
@ -44,7 +44,7 @@
resultQuery = search === '' ? { ...query } : { ...query, $search: search }
$: if (!label && title) {
translate(title, {}, $themeStore.language).then((res) => {
translateCB(title, {}, $themeStore.language, (res) => {
label = res
})
}

View File

@ -19,7 +19,7 @@
</script>
<div class="root flex-gap-1">
{#each $tabsStore as tab}
{#each $tabsStore as tab (tab._id)}
<WorkbenchTabPresenter {tab} />
{/each}
<div class="ml-1-5 plus-button mr-1">

View File

@ -41,8 +41,9 @@
"eslint-config-standard-with-typescript": "^40.0.0",
"prettier": "^3.1.0",
"typescript": "^5.3.3",
"@playwright/test": "^1.41.2",
"allure-playwright": "^2.9.2",
"@playwright/test": "^1.47.2",
"allure-playwright": "^3.0.4",
"allure-js-commons": "^3.0.4",
"@faker-js/faker": "^8.4.1"
},
"dependencies": {

View File

@ -1,5 +1,5 @@
import { Browser, Locator, Page } from '@playwright/test'
import { allure } from 'allure-playwright'
import { attachment } from 'allure-js-commons'
export const PlatformURI = process.env.PLATFORM_URI as string
export const PlatformTransactor = process.env.PLATFORM_TRANSACTOR as string
@ -58,7 +58,7 @@ export function randomString (): string {
}
export async function attachScreenshot (name: string, page: Page): Promise<void> {
await allure.attachment(name, await page.screenshot(), {
await attachment(name, await page.screenshot(), {
contentType: 'image/png'
})
await page.screenshot({ path: `screenshots/${name}` })

View File

@ -1,6 +1,6 @@
<script lang="ts">
import { DocumentQuery, Ref, Space, WithLookup } from '@hcengineering/core'
import { IntlString, translate } from '@hcengineering/platform'
import { IntlString, translate, translateCB } from '@hcengineering/platform'
import { Button, IModeSelector, IconDetails, IconDetailsFilled, themeStore } from '@hcengineering/ui'
import { ViewOptions, Viewlet } from '@hcengineering/view'
import { FilterBar, SpaceHeader, ViewletContentView, ViewletSettingButton } from '@hcengineering/view-resources'
@ -26,7 +26,7 @@
let resultQuery: DocumentQuery<GithubPullRequest> = { ...searchQuery }
$: if (!label && title) {
void translate(title, {}, $themeStore.language).then((res) => {
translateCB(title, {}, $themeStore.language, (res) => {
label = res
})
}

View File

@ -14,9 +14,9 @@
-->
<script lang="ts">
import { WithLookup } from '@hcengineering/core'
import { translate } from '@hcengineering/platform'
import { Icon, themeStore } from '@hcengineering/ui'
import { GithubIntegrationRepository } from '@hcengineering/github'
import { translateCB } from '@hcengineering/platform'
import { Icon, themeStore } from '@hcengineering/ui'
import github from '../plugin'
export let value: WithLookup<GithubIntegrationRepository> | undefined
@ -33,13 +33,9 @@
$: if (value !== undefined) {
label = value.name
} else {
translate(github.string.NoRepository, {}, $themeStore.language)
.then((r) => {
label = r
})
.catch((err) => {
console.error(err)
})
translateCB(github.string.NoRepository, {}, $themeStore.language, (r) => {
label = r
})
}
$: disabled = disabled || value === undefined
</script>

View File

@ -1,5 +1,5 @@
FROM node:20
FROM node:22
WORKDIR /usr/src/app

View File

@ -41,8 +41,9 @@
"eslint-config-standard-with-typescript": "^40.0.0",
"prettier": "^3.1.0",
"typescript": "^5.3.3",
"@playwright/test": "^1.41.2",
"allure-playwright": "^2.9.2",
"@playwright/test": "^1.47.2",
"allure-playwright": "^3.0.4",
"allure-js-commons": "^3.0.4",
"@faker-js/faker": "^8.4.1"
},
"dependencies": {

View File

@ -1,6 +1,6 @@
import { faker } from '@faker-js/faker'
import { APIRequestContext, Browser, BrowserContext, Locator, Page, expect } from '@playwright/test'
import { allure } from 'allure-playwright'
import { attachment } from 'allure-js-commons'
import path from 'path'
import { ApiEndpoint } from './API/Api'
import { TestData } from './chat/types'
@ -169,7 +169,7 @@ export async function * iterateLocator (locator: Locator): AsyncGenerator<Locato
}
export async function attachScreenshot (name: string, page: Page): Promise<void> {
await allure.attachment(name, await page.screenshot(), {
await attachment(name, await page.screenshot(), {
contentType: 'image/png'
})
await page.screenshot({ path: `screenshots/${name}` })