diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 45b25530c5e..fa605872d0a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -76,6 +76,10 @@ jobs: - name: Checking for mis-matching dependencies... run: node common/scripts/install-run-rush.js check + - name: Prepare .npmrc for GitHub Packages + run: | + echo "//npm.pkg.github.com/:_authToken=${{secrets.GITHUB_TOKEN}}" > ~/.npmrc + - name: Installing... run: node common/scripts/install-run-rush.js install @@ -226,6 +230,10 @@ jobs: - name: Checking for mis-matching dependencies... run: node common/scripts/install-run-rush.js check + - name: Prepare .npmrc for GitHub Packages + run: | + echo "//npm.pkg.github.com/:_authToken=${{secrets.GITHUB_TOKEN}}" > ~/.npmrc + - name: Installing... run: node common/scripts/install-run-rush.js install @@ -350,6 +358,10 @@ jobs: - name: Checking for mis-matching dependencies... run: node common/scripts/install-run-rush.js check + - name: Prepare .npmrc for GitHub Packages + run: | + echo "//npm.pkg.github.com/:_authToken=${{secrets.GITHUB_TOKEN}}" > ~/.npmrc + - name: Installing... run: node common/scripts/install-run-rush.js install @@ -423,6 +435,10 @@ jobs: - name: Checking for mis-matching dependencies... run: node common/scripts/install-run-rush.js check + - name: Prepare .npmrc for GitHub Packages + run: | + echo "//npm.pkg.github.com/:_authToken=${{secrets.GITHUB_TOKEN}}" > ~/.npmrc + - name: Installing... run: node common/scripts/install-run-rush.js install @@ -495,6 +511,10 @@ jobs: - name: Checking for mis-matching dependencies... run: node common/scripts/install-run-rush.js check + - name: Prepare .npmrc for GitHub Packages + run: | + echo "//npm.pkg.github.com/:_authToken=${{secrets.GITHUB_TOKEN}}" > ~/.npmrc + - name: Installing... run: node common/scripts/install-run-rush.js install @@ -595,6 +615,10 @@ jobs: restore-keys: | ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/pnpm-lock.yaml') }} + - name: Prepare .npmrc for GitHub Packages + run: | + echo "//npm.pkg.github.com/:_authToken=${{secrets.GITHUB_TOKEN}}" > ~/.npmrc + - name: Installing... run: node common/scripts/install-run-rush.js install @@ -668,6 +692,10 @@ jobs: restore-keys: | ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/pnpm-lock.yaml') }} + - name: Prepare .npmrc for GitHub Packages + run: | + echo "//npm.pkg.github.com/:_authToken=${{secrets.GITHUB_TOKEN}}" > ~/.npmrc + - name: Installing... run: node common/scripts/install-run-rush.js install --purge - name: Model version from git tags diff --git a/.vscode/launch.json b/.vscode/launch.json index 164f4d12d1d..c654de56c13 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -868,6 +868,25 @@ "runtimeArgs": ["--nolazy", "-r", "ts-node/register"], "sourceMaps": true, "cwd": "${workspaceRoot}/services/export/pod-export" + }, + { + "name": "Msg2File", + "type": "node", + "request": "launch", + "args": ["src/index.ts"], + "env": { + "ACCOUNTS_URL": "http://localhost:3000", + "DB_URL": "postgresql://root@localhost:26257/defaultdb?sslmode=disable", + "PORT": "9087", + "SECRET": "secret", + "SERVICE_ID": "msg2file-service", + "STORAGE_CONFIG": "minio|localhost?accessKey=minioadmin&secretKey=minioadmin" + }, + "runtimeVersion": "20", + "runtimeArgs": ["--nolazy", "-r", "ts-node/register"], + "sourceMaps": true, + "outputCapture": "std", + "cwd": "${workspaceRoot}/services/msg2file" } ] } diff --git a/common/config/rush/.npmrc b/common/config/rush/.npmrc index b902e270ccd..c88d4d6a52d 100644 --- a/common/config/rush/.npmrc +++ b/common/config/rush/.npmrc @@ -19,4 +19,5 @@ # //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} # registry=https://registry.npmjs.org/ +@hcengineering:registry=https://npm.pkg.github.com always-auth=false diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index a45fcf452a6..30be24dc5d1 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -34,6 +34,27 @@ importers: '@faker-js/faker': specifier: ^8.4.1 version: 8.4.1 + '@hcengineering/communication-client-query': + specifier: 0.1.147 + version: 0.1.147(typescript@5.3.3) + '@hcengineering/communication-rest-client': + specifier: 0.1.147 + version: 0.1.147(typescript@5.3.3) + '@hcengineering/communication-sdk-types': + specifier: 0.1.147 + version: 0.1.147(typescript@5.3.3) + '@hcengineering/communication-server': + specifier: 0.1.147 + version: 0.1.147(typescript@5.3.3) + '@hcengineering/communication-shared': + specifier: 0.1.147 + version: 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': + specifier: 0.1.147 + version: 0.1.147(typescript@5.3.3) + '@hcengineering/communication-yaml': + specifier: 0.1.147 + version: 0.1.147(typescript@5.3.3) '@hocuspocus/provider': specifier: ^2.11.0 version: 2.11.2(bufferutil@4.0.8)(utf-8-validate@6.0.4)(y-protocols@1.0.6(yjs@13.6.23))(yjs@13.6.23) @@ -160,6 +181,15 @@ importers: '@rush-temp/card-resources': specifier: file:./projects/card-resources.tgz version: file:projects/card-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@tiptap/pm@2.11.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + '@rush-temp/chat': + specifier: file:./projects/chat.tgz + version: file:projects/chat.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + '@rush-temp/chat-assets': + specifier: file:./projects/chat-assets.tgz + version: file:projects/chat-assets.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + '@rush-temp/chat-resources': + specifier: file:./projects/chat-resources.tgz + version: file:projects/chat-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) '@rush-temp/chunter': specifier: file:./projects/chunter.tgz version: file:projects/chunter.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) @@ -325,6 +355,15 @@ importers: '@rush-temp/importer': specifier: file:./projects/importer.tgz version: file:projects/importer.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + '@rush-temp/inbox': + specifier: file:./projects/inbox.tgz + version: file:projects/inbox.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + '@rush-temp/inbox-assets': + specifier: file:./projects/inbox-assets.tgz + version: file:projects/inbox-assets.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + '@rush-temp/inbox-resources': + specifier: file:./projects/inbox-resources.tgz + version: file:projects/inbox-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) '@rush-temp/inventory': specifier: file:./projects/inventory.tgz version: file:projects/inventory.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) @@ -412,6 +451,9 @@ importers: '@rush-temp/model-card': specifier: file:./projects/model-card.tgz version: file:projects/model-card.tgz + '@rush-temp/model-chat': + specifier: file:./projects/model-chat.tgz + version: file:projects/model-chat.tgz '@rush-temp/model-chunter': specifier: file:./projects/model-chunter.tgz version: file:projects/model-chunter.tgz @@ -448,6 +490,9 @@ importers: '@rush-temp/model-hr': specifier: file:./projects/model-hr.tgz version: file:projects/model-hr.tgz + '@rush-temp/model-inbox': + specifier: file:./projects/model-inbox.tgz + version: file:projects/model-inbox.tgz '@rush-temp/model-inventory': specifier: file:./projects/model-inventory.tgz version: file:projects/model-inventory.tgz @@ -724,6 +769,9 @@ importers: '@rush-temp/pod-mail': specifier: file:./projects/pod-mail.tgz version: file:projects/pod-mail.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9)) + '@rush-temp/pod-msg2file': + specifier: file:./projects/pod-msg2file.tgz + version: file:projects/pod-msg2file.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9)) '@rush-temp/pod-print': specifier: file:./projects/pod-print.tgz version: file:projects/pod-print.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(bufferutil@4.0.8)(utf-8-validate@6.0.4) @@ -1228,6 +1276,9 @@ importers: '@rush-temp/ui': specifier: file:./projects/ui.tgz version: file:projects/ui.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + '@rush-temp/ui-next': + specifier: file:./projects/ui-next.tgz + version: file:projects/ui-next.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) '@rush-temp/uploader': specifier: file:./projects/uploader.tgz version: file:projects/uploader.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) @@ -1477,6 +1528,9 @@ importers: '@types/node': specifier: ~20.11.16 version: 20.11.19 + '@types/node-cron': + specifier: ^3.0.11 + version: 3.0.11 '@types/node-fetch': specifier: ~2.6.2 version: 2.6.11 @@ -1873,6 +1927,9 @@ importers: msgpackr-extract: specifier: ^3.0.3 version: 3.0.3 + node-cron: + specifier: ^3.0.3 + version: 3.0.3 node-fetch: specifier: ^2.6.6 version: 2.7.0(encoding@0.1.13) @@ -2873,6 +2930,75 @@ packages: '@gar/promisify@1.1.3': resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + '@hcengineering/account-client@0.7.28': + resolution: {integrity: sha512-k1dkioX+jYrLyAXLLLsBYVCdZKf3WjhnDHw/yeAQgLQQ/9W2ffLtDMZ8lYWV3XMQ3eWrUCodtTDOiAQgXd/LEQ==, tarball: https://npm.pkg.github.com/download/@hcengineering/account-client/0.7.28/32c9bc0dd297f00f4d5461467f25e072d01b9c76} + + '@hcengineering/analytics@0.7.28': + resolution: {integrity: sha512-+CI/wJ8zgop+3mEcvhlB1UJBU6tIKq2Y7qTichZjGli8BckEIEwbD4j2beu2qXRSoTT2yUGWM9zpS9+fmH/DAw==, tarball: https://npm.pkg.github.com/download/@hcengineering/analytics/0.7.28/a8faf3d575bb28b9682b659495e738f8e0ca596e} + + '@hcengineering/card@0.7.28': + resolution: {integrity: sha512-1d3allyx9jTpE/gr9kk/g5qo5848i4FKsRiHgCpJqzNEdRW7TAednoHAr2hKRU5DZC/i3Br56axSkUQzV2Idhg==, tarball: https://npm.pkg.github.com/download/@hcengineering/card/0.7.28/5348996f5b7b4a34517780a5bf324122cbddfbad} + + '@hcengineering/communication-client-query@0.1.147': + resolution: {integrity: sha512-HwMxBJnQ6bx17lCDQGkRiyd2XhA8XnjmEw3iymEXTdCvRgNF3rJ0kdrhk9GNUEqiTGnD9WrNDKHzKsVsqQhpGg==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-client-query/0.1.147/db4625e2082d71b66584b11e186186eda6106125} + peerDependencies: + typescript: ^5.6.3 + + '@hcengineering/communication-cockroach@0.1.147': + resolution: {integrity: sha512-L0DJNDXJ2otmRryOU8eHEjkGhORjQhoqJUW32zsBTSPOKs2qS/WrtKW7nqR1xWVXuOuKEhGf3dybA9JqhkHAMA==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-cockroach/0.1.147/a7ddcc184d42ee4afc10fe0b09860bc1f09c9878} + peerDependencies: + typescript: ^5.6.3 + + '@hcengineering/communication-query@0.1.147': + resolution: {integrity: sha512-etTQ1yb3uiQVw4QO9zWj21jtccmnLT1gLwTnFx4RhEJoNbtfOg4W82osH46dbgxvEEtx+sCAfRgVASihYT2mmg==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-query/0.1.147/013b01723ef19815c514a15290807afa8bd1de0c} + peerDependencies: + typescript: ^5.6.3 + + '@hcengineering/communication-rest-client@0.1.147': + resolution: {integrity: sha512-/ukvmBwC9kSicHr7phzGsJSJmBEIhoZRRDbsJJpEY9tMUuzzKwuohxShodpYWkggfZzP1bmwO1w0IThzAH1RLg==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-rest-client/0.1.147/5242df482a81e24bf1c079847c9343ce1843d5a7} + peerDependencies: + typescript: ^5.6.3 + + '@hcengineering/communication-sdk-types@0.1.147': + resolution: {integrity: sha512-ktCOc+g9t+iFe4lLZmPV2xtXGtYhJpAS4TAHvELjF+q20PG1A8KcV01ZWuR0ixHk7yZ1MS9XxXxAEj7vMlNO8g==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-sdk-types/0.1.147/a08ddf1af10115d98ce20f2cc0ddada01f77f64d} + peerDependencies: + typescript: ^5.6.3 + + '@hcengineering/communication-server@0.1.147': + resolution: {integrity: sha512-f7a2MIHmX3iiMf/ZIDHQye2Ls+74AiMtdbcFFl0Ks++HbsWZmHg5Z7+jOMeVikiJRMemhl2vNKNzwGE+X7T94w==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-server/0.1.147/ec146d11963bf734d0b71a731aaf906aba05a481} + peerDependencies: + typescript: ^5.6.3 + + '@hcengineering/communication-shared@0.1.147': + resolution: {integrity: sha512-TKOuVCEovwA6O0ETzkxjlFPrtqvtPDotSSNcEDO6o9jL3Wx/FbiczovF7YW2EeUNyW63zE2ckaMT3g0aqbtQ4Q==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-shared/0.1.147/90daedd7c77c431eb4e1bd25f38e29fe7f038ea4} + peerDependencies: + typescript: ^5.6.3 + + '@hcengineering/communication-types@0.1.147': + resolution: {integrity: sha512-5B5KGWmfbzQ8E7Ga8iPAXfVitB9xf2Oc8hBZDnAw+aMQweOTUDFDcU5IvybAGKgCWPyMVHiiY/p4IP+C5p42wQ==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-types/0.1.147/131a97d82ef3358588f789b949ee269bad344717} + peerDependencies: + typescript: ^5.6.3 + + '@hcengineering/communication-yaml@0.1.147': + resolution: {integrity: sha512-IDI+7hOevwReS2rpHgR+BTIY/eCgoAbE10JIizMJYVOaopT1QYvIyAExkzca7Mgt7T6JBsdz5t7x6cltWLOMXg==, tarball: https://npm.pkg.github.com/download/@hcengineering/communication-yaml/0.1.147/62fe45844f090702eab434edf99a0ebb924c0800} + peerDependencies: + typescript: ^5.6.3 + + '@hcengineering/core@0.7.28': + resolution: {integrity: sha512-qv4QE7mkect6JYlGMljW5CQ2uU80hFGq0E17lZ5rO79h1boWEKLJpINv+w3J2BdR/nNG7taIsdZg3yfl9fY4bg==, tarball: https://npm.pkg.github.com/download/@hcengineering/core/0.7.28/43b84c63262e2b8fe5554c1967812e2ce6bb56e1} + + '@hcengineering/platform@0.7.28': + resolution: {integrity: sha512-0zEifwsLdOs/M6TZ9xnPrQTTlhwW28sooiyL4ZfQsiC2AJUy05vLP5/W8V9eDLta+EiR5bjtlulGsg1GfPjUoQ==, tarball: https://npm.pkg.github.com/download/@hcengineering/platform/0.7.28/2126ff97284b679ceab3c86f24febd73a3a28712} + + '@hcengineering/server-token@0.7.28': + resolution: {integrity: sha512-TaHwzxuoFKN6jnWHIZk0UcRmB+UQ1QE1HZzUh5doPSFUYOAtTrSb32iJDA8e8oEADcJpOp9RGIUP/EP/VED7BQ==, tarball: https://npm.pkg.github.com/download/@hcengineering/server-token/0.7.28/b1cffcb628aa0c6ac73171ef340c8ccf0f85ab07} + + '@hcengineering/theme@0.7.28': + resolution: {integrity: sha512-Hv3wQKHr327TC7wMHCBiG4bMtg8vSlb7+UFwdKI8ztEs3359meqkXu+exqi7Nl5334voXIz5ZFxjwZwOMzNSFA==, tarball: https://npm.pkg.github.com/download/@hcengineering/theme/0.7.28/557640a7ba2ffaa4d6e5411a54577f60dc528300} + + '@hcengineering/ui@0.7.28': + resolution: {integrity: sha512-QsUpO0+Idu1n2dC6KtorPJ6SSp30It8FHSuG3Y+Awv4td/ftVocOSFqhskbk+us9Yw9KqOYgkqhGYEHbfRfw4Q==, tarball: https://npm.pkg.github.com/download/@hcengineering/ui/0.7.28/82025fc775702ea8c8569611356662bfbf28eb74} + '@hocuspocus/common@2.11.2': resolution: {integrity: sha512-Ej3ehUYweYrlVArYdKe3grvEDO2wbjpy/IoZrtklHI4ydChLkXJCT6nTelM69dOtDG8IfX9WPIXiwwJF7CGNcA==} @@ -3752,7 +3878,7 @@ packages: version: 0.0.0 '@rush-temp/activity-resources@file:projects/activity-resources.tgz': - resolution: {integrity: sha512-CFkb+ZYcPjz1Hqvuzr2gTQ+dp7Fasi8Y5eefOldw+pw9GIvfRlURwnZJo6zMPOcvCNgUu9JmR3qhb/eXIZfKBw==, tarball: file:projects/activity-resources.tgz} + resolution: {integrity: sha512-PdvIilzj+cWxxM80W3oTaMJWi6w10VKkZ+EMPhD4ME//+EQPsX/NDTNuljhEgY+ASrkhLb1YNeViZjWG4chYig==, tarball: file:projects/activity-resources.tgz} version: 0.0.0 '@rush-temp/activity@file:projects/activity.tgz': @@ -3863,6 +3989,18 @@ packages: resolution: {integrity: sha512-/vbzO3L239DHkxNpG5cw/ngDrvuvXrRcoq46Y7uJzNwSNAOMpiiRSMdpj4dr2bmPXEhkFGPeA0mKLJwXLseEhw==, tarball: file:projects/card.tgz} version: 0.0.0 + '@rush-temp/chat-assets@file:projects/chat-assets.tgz': + resolution: {integrity: sha512-qSZPc4+GkNPYMdf7O+hh7fPSiw5eEP0SNh/ifTIEBeh6gPs2TaJSlz3MlHGIy4+YkK+9WpLFpNco3dYU3Nsjrw==, tarball: file:projects/chat-assets.tgz} + version: 0.0.0 + + '@rush-temp/chat-resources@file:projects/chat-resources.tgz': + resolution: {integrity: sha512-QBFfFFEyqYAD7r/qIwa2kEOeYeFMzT62HIzSHc5ErAl9nNGqLX3aNyr+SR1dCq4wtzaCUDrmAhAyAF5BuRtN6A==, tarball: file:projects/chat-resources.tgz} + version: 0.0.0 + + '@rush-temp/chat@file:projects/chat.tgz': + resolution: {integrity: sha512-YMgHqdsfHA8zdu6ohS0lD7vonC0QiUmbakYqWqE+ZpypaQpa72mT1mkz+RRS29Kewx34ObDYzPby20yp3SuR0g==, tarball: file:projects/chat.tgz} + version: 0.0.0 + '@rush-temp/chunter-assets@file:projects/chunter-assets.tgz': resolution: {integrity: sha512-cvDTBdx4bEvd+Bv01aNUJVclk4+Y48bAg6eE3Pllly5LTd3AThx+Txq6YlFo8YkbSiKlxwMfBBWt/XLlxSKhPA==, tarball: file:projects/chunter-assets.tgz} version: 0.0.0 @@ -3876,7 +4014,7 @@ packages: version: 0.0.0 '@rush-temp/client-resources@file:projects/client-resources.tgz': - resolution: {integrity: sha512-s2VP7YDaXR6VMITb2/kgWe69RxM1XaTdNHQJfliJfFaV88egZSK6JNmB40FoA/QY0Vvf7SmJH/Ld+bvjZqGpWA==, tarball: file:projects/client-resources.tgz} + resolution: {integrity: sha512-DanlN6UBEDfEyzmltHnd2K3ITQUzYjs085e0g/b4kbuAIE8EOxwOWzsFenSz2wanLWD5QV1TDyN6/xvfjTIlOQ==, tarball: file:projects/client-resources.tgz} version: 0.0.0 '@rush-temp/client@file:projects/client.tgz': @@ -3944,7 +4082,7 @@ packages: version: 0.0.0 '@rush-temp/desktop@file:projects/desktop.tgz': - resolution: {integrity: sha512-/5CR2/cxaoAuPTKDfodv7kh/15tzza/f//7LzRIP48bO3Eoay+x7OXU3Gz+zcV46uLWTb+bXdJ1015B2Ao4x4g==, tarball: file:projects/desktop.tgz} + resolution: {integrity: sha512-kJTxaXhLxQPR7NO0NoDa7YOHKOgOZvjbHWB20eH2ge7hj16MkXlH8q4aqrizcNk1Wy7Q19lhQifgkdDYc0xy7w==, tarball: file:projects/desktop.tgz} version: 0.0.0 '@rush-temp/devmodel-resources@file:projects/devmodel-resources.tgz': @@ -4083,6 +4221,18 @@ packages: resolution: {integrity: sha512-DecPpuedBGqrUXATVoljf098pHTQ9zqylXrUKbWiibuuFy5i9zzw/9HY8hM4Zg1Ku8ZOm1AGBUoSmgmGPJ13Cg==, tarball: file:projects/importer.tgz} version: 0.0.0 + '@rush-temp/inbox-assets@file:projects/inbox-assets.tgz': + resolution: {integrity: sha512-DvENcy2MvfaePC482w3flW1nstrMK43PWOcqL+LIvMfpwe1ezJ1NckGldKCjd9OarmV3ANc5iBj1DotsqqpfyQ==, tarball: file:projects/inbox-assets.tgz} + version: 0.0.0 + + '@rush-temp/inbox-resources@file:projects/inbox-resources.tgz': + resolution: {integrity: sha512-pDZVuBnQF8guoNFYpzMi+sQfzmZVto48PKsXQPy150oLozKV9D7tVG5bpev5KX9vmB/Y6SKhLbvb7oTDhL7hKw==, tarball: file:projects/inbox-resources.tgz} + version: 0.0.0 + + '@rush-temp/inbox@file:projects/inbox.tgz': + resolution: {integrity: sha512-UY+dNjb69CwhXQm/XPnyY0Ngn1w6GBaB+uokG/4gpUkdNGsibBGfjxffhXUmds5O0dgd9fkafhcZKbPQv0HayQ==, tarball: file:projects/inbox.tgz} + version: 0.0.0 + '@rush-temp/inventory-assets@file:projects/inventory-assets.tgz': resolution: {integrity: sha512-Uayr70kuiNfwBgNoFcu1rkWhdHhnbg7aEDcbozbhn5Eyel/B6he2uUYxPZc2gl1VUiEA8KBGszSAEXMs0YER0A==, tarball: file:projects/inventory-assets.tgz} version: 0.0.0 @@ -4168,7 +4318,7 @@ packages: version: 0.0.0 '@rush-temp/model-all@file:projects/model-all.tgz': - resolution: {integrity: sha512-C7Qm2DZVdjmEr+JjxYTonHSqDGYGGfZXeGdiPRGBAu/vhgBK+1VZrN+awx9Z1gLIX3A2brjigZx4Ixk22Z5igQ==, tarball: file:projects/model-all.tgz} + resolution: {integrity: sha512-xaEuhcBAtplQqvLIRIQLhWnphNupk2Gz8DYBvuNscTUI3Lk5DC8upfHOLY4qepYTnsnvhl88lWWGfnRu0sa3sQ==, tarball: file:projects/model-all.tgz} version: 0.0.0 '@rush-temp/model-analytics-collector@file:projects/model-analytics-collector.tgz': @@ -4195,6 +4345,10 @@ packages: resolution: {integrity: sha512-diGAGkQiQNXD27/ln6i6al/sr7X2dOUdiTx6114JOahvZngprIhzdJLdXuW44BnQHTugr4j0Sp1zOwQXKcTBVA==, tarball: file:projects/model-card.tgz} version: 0.0.0 + '@rush-temp/model-chat@file:projects/model-chat.tgz': + resolution: {integrity: sha512-OuLdR05w3mKXbRksmTM4ZC5Cmm757vz4gUH08PHzDVtrOJU/gq4lkAhdqzFgEKnV8nXN4mZ7Cn3Ra/1NDAcKuQ==, tarball: file:projects/model-chat.tgz} + version: 0.0.0 + '@rush-temp/model-chunter@file:projects/model-chunter.tgz': resolution: {integrity: sha512-es0oJ+MzCyOR75Kdx2An+tBhga3cZCaPV24k7V4LtlxXyxmboZjiDhZgh9/56psQwWgT7qqL6XBPzCR4nZBV1g==, tarball: file:projects/model-chunter.tgz} version: 0.0.0 @@ -4243,6 +4397,10 @@ packages: resolution: {integrity: sha512-OlNh9RFpldQeaG84GJoFFhuvXZ+49hnNK2sxBJSo4YwNVojM0Mf4tccfD6Hpbj/T1Iiyqc7LVSigtPHTX8UtDQ==, tarball: file:projects/model-hr.tgz} version: 0.0.0 + '@rush-temp/model-inbox@file:projects/model-inbox.tgz': + resolution: {integrity: sha512-dEaSNw5aHjx55LODcLfVAPlI3O96QC1JWCOd4Lc5aNIJihx4x+RewBRSNHd5NMUNTDlaAIDobcSn1LlaGitNMQ==, tarball: file:projects/model-inbox.tgz} + version: 0.0.0 + '@rush-temp/model-inventory@file:projects/model-inventory.tgz': resolution: {integrity: sha512-T2z4UFNKsz19S/iDr8/z07rrc2TMgE/D8yjrjWibo19Pvi13i7nzdXCczj1gx2IQY8sm6X3kpn7cR76QGTvGEw==, tarball: file:projects/model-inventory.tgz} version: 0.0.0 @@ -4308,7 +4466,7 @@ packages: version: 0.0.0 '@rush-temp/model-server-activity@file:projects/model-server-activity.tgz': - resolution: {integrity: sha512-vHyRXeWXMy2saZVCwBJzXZynRIKxiIPqBw1FUEChl1H2S3xoPkdnozIDRjMtJAPwIKsxlNcWD38/C4O0reX6Tg==, tarball: file:projects/model-server-activity.tgz} + resolution: {integrity: sha512-NSvdndUREqSGzapSo3VoMV2/iPU7Nuy0XdYk+XFck8O62uQSHQAeuoq0yhX8jZ0xfDEVT/c05CDKoKJMzDbXlQ==, tarball: file:projects/model-server-activity.tgz} version: 0.0.0 '@rush-temp/model-server-ai-bot@file:projects/model-server-ai-bot.tgz': @@ -4615,12 +4773,16 @@ packages: resolution: {integrity: sha512-jAdMLPMqs82cRy4ZUvhNJH8S1dO+25xCBl/Xkrdg/JTDI9dp1mE1tqthuwvQ/erGB0uqditAX+FXJgqKG1gq7Q==, tarball: file:projects/pod-mail.tgz} version: 0.0.0 + '@rush-temp/pod-msg2file@file:projects/pod-msg2file.tgz': + resolution: {integrity: sha512-p6QiGG2pfCWeeqzEd4uywXjHRtdDV91ij+t7mDW3upE6hFPuI5dZR3JAqR7CMARmgI6JnB+PozXtFVtzkAtP7w==, tarball: file:projects/pod-msg2file.tgz} + version: 0.0.0 + '@rush-temp/pod-print@file:projects/pod-print.tgz': resolution: {integrity: sha512-KNZrBeofhGFWQHMd1aPU7smmL50h/fGw4tXy7bEV2PcO14vphe2MyMfuWcTw1ksmeXFP6V3C2XxmgKFk+DT0dg==, tarball: file:projects/pod-print.tgz} version: 0.0.0 '@rush-temp/pod-server@file:projects/pod-server.tgz': - resolution: {integrity: sha512-toWgesqQWTYgkwA6VPDiaJJc7ZmDkHFzNg/MbDjSACtmy0/endv3ioglyXYdoDo/m4IbFZOghMUJOZbQgQvRUA==, tarball: file:projects/pod-server.tgz} + resolution: {integrity: sha512-w1DkP6VOrevA7f9SyoqMxPN0o0pI73pGpI/Gb2FGVP5Zd4eX6IViOyPhAsViD1zfgH1xpSlDKw/9HoCI2/oQeA==, tarball: file:projects/pod-server.tgz} version: 0.0.0 '@rush-temp/pod-ses@file:projects/pod-ses.tgz': @@ -4668,7 +4830,7 @@ packages: version: 0.0.0 '@rush-temp/presentation@file:projects/presentation.tgz': - resolution: {integrity: sha512-8PjrEJ4Myv1tw8UzIITEXnaEq6wkmHrwgVqVXUwIIfDIJHSeNxoEIZOQXddhr+eDcpn9yweksJl8cMF65qzSpw==, tarball: file:projects/presentation.tgz} + resolution: {integrity: sha512-KzvG68Xil8hU71r/JUW41psGFqkSNJ7IJJlX3qzZXpDXiNMp320V7n6FZheMIjEjOOpSkIdFrBh7F4zWOPmssw==, tarball: file:projects/presentation.tgz} version: 0.0.0 '@rush-temp/print-assets@file:projects/print-assets.tgz': @@ -4696,7 +4858,7 @@ packages: version: 0.0.0 '@rush-temp/prod@file:projects/prod.tgz': - resolution: {integrity: sha512-YbeJrXfluzSO+TbT2dg5gbUaWiwJcQJvHvlooBLDBPhB/+cTpgUVaSxbilYDN84PQkRe/JD8LHVrO0VmpQ6QIQ==, tarball: file:projects/prod.tgz} + resolution: {integrity: sha512-yFKF/Lsa6PxYmLOAb9kyolI4Fh/n7KTQ+EfPL5vPz6eF/XOyZPli5MAZ5DznWQmooD47OvC6u+5NunGZTxhE2g==, tarball: file:projects/prod.tgz} version: 0.0.0 '@rush-temp/products-assets@file:projects/products-assets.tgz': @@ -4796,7 +4958,7 @@ packages: version: 0.0.0 '@rush-temp/server-activity-resources@file:projects/server-activity-resources.tgz': - resolution: {integrity: sha512-WOpRUTKDfLgj6GTJOX+gFiv1Tcxi9zFIn9sCJJcWTEfxEL9Oor5/i7fBMNWi5eqGYCbwMdO72tyFDeZwjsmAnw==, tarball: file:projects/server-activity-resources.tgz} + resolution: {integrity: sha512-7eTT0jMFdpooIE3f+Oa9wgbnkGZ0sdHQ0tVPaqRtOEcanC1Gm18uyRMowQrBltFy6QBRljhFnexklQq3Qs0mfw==, tarball: file:projects/server-activity-resources.tgz} version: 0.0.0 '@rush-temp/server-activity@file:projects/server-activity.tgz': @@ -4840,7 +5002,7 @@ packages: version: 0.0.0 '@rush-temp/server-card-resources@file:projects/server-card-resources.tgz': - resolution: {integrity: sha512-x6WAVDpr6jvxJfo4XR+mkxbsKeZkp9YCndmJzLGEK/qaankXgnWax5n4pJhohJWbsE/qEuEYYqKl1h6fCMXzPA==, tarball: file:projects/server-card-resources.tgz} + resolution: {integrity: sha512-lk6f1Vc81IawMk8qwJkmgUwm74kluODJiThLyHyzDxJsyq/5e4EluRlQV8wDmE7yogBK4vYj3fUG375XfR/eWg==, tarball: file:projects/server-card-resources.tgz} version: 0.0.0 '@rush-temp/server-card@file:projects/server-card.tgz': @@ -4884,7 +5046,7 @@ packages: version: 0.0.0 '@rush-temp/server-core@file:projects/server-core.tgz': - resolution: {integrity: sha512-X7cOEFN/pZlejHJcS8dx8CGGOtRl3iBttMm4P8N/bcsU848IDlX0WiLmRI52ZLm9UAgOpmIpv3pBdUVt9N2Z+Q==, tarball: file:projects/server-core.tgz} + resolution: {integrity: sha512-QwktG4aJQCqtU6z2lcKc9kSO/wTNDdd+ewjNq+lCa/asNfiy1Aq+rklWCS2k47SLAaSrv1nLb7T2MFAepj2xrA==, tarball: file:projects/server-core.tgz} version: 0.0.0 '@rush-temp/server-document-resources@file:projects/server-document-resources.tgz': @@ -5092,7 +5254,7 @@ packages: version: 0.0.0 '@rush-temp/server@file:projects/server.tgz': - resolution: {integrity: sha512-378GorQHM5ihU3dZLis+aq/JRjXeIgVOzIV/W3k27KB8EzoZGDbZQbDuKC07vAPxNBaoJ5yYcLTdGWx6XHnwzw==, tarball: file:projects/server.tgz} + resolution: {integrity: sha512-NmrJLMu57xujIbGyIYEb7CQfwMqS7tsPq2TLCNVXrqr+eId8E1sf7l8hnMkwWsqfMbVy1sI8/aOH/S82jpiGnA==, tarball: file:projects/server.tgz} version: 0.0.0 '@rush-temp/setting-assets@file:projects/setting-assets.tgz': @@ -5283,6 +5445,10 @@ packages: resolution: {integrity: sha512-NpJv8uZg40kGk81CXrjSDm0neHxVDF0h+tn1dfLHOk2wM4bstKDK6ZvtvAEYBkLSvdfui7/DVqOVkjtBKs6SoA==, tarball: file:projects/training.tgz} version: 0.0.0 + '@rush-temp/ui-next@file:projects/ui-next.tgz': + resolution: {integrity: sha512-vwalWN9E1vdB44+E9osMRRzp0d0516ZYK0yjzgaYZrWDQLaiWwYmHe+XlO+kSL/DP6PDhdhMDHJ1BQg9hlLhTA==, tarball: file:projects/ui-next.tgz} + version: 0.0.0 + '@rush-temp/ui@file:projects/ui.tgz': resolution: {integrity: sha512-0U0x2FrKQNlJteRKEqKkDhZNC/qOWO/rL3qK8cuqdYR7Gz5kCaQBnRRHYWGDTVtUKcyYrUN+2RTaB/OG5pgYhA==, tarball: file:projects/ui.tgz} version: 0.0.0 @@ -5316,7 +5482,7 @@ packages: version: 0.0.0 '@rush-temp/workbench-resources@file:projects/workbench-resources.tgz': - resolution: {integrity: sha512-wnOyuF9Gv2lBWbszQxpfxQ1fF15tG9toi26+Bt8IONSejZsaDrQw/rXhZsW9wgWbtoRnD17Gjg5G2YUPzWZvUg==, tarball: file:projects/workbench-resources.tgz} + resolution: {integrity: sha512-N00MR4MXHz3pMLbTWfIwQCKUpwtaLTtx2lu+UR9QYhn2CiMT/tyVqfxtN2Pkbf0sj5VG5euI6jsnKskYgUY74g==, tarball: file:projects/workbench-resources.tgz} version: 0.0.0 '@rush-temp/workbench@file:projects/workbench.tgz': @@ -6226,6 +6392,9 @@ packages: '@types/mysql@2.15.26': resolution: {integrity: sha512-DSLCOXhkvfS5WNNPbfn2KdICAmk8lLc+/PNvnPnF7gOdMZCxopXduqv0OQ13y/yA/zXTSikZZqVgybUxOEg6YQ==} + '@types/node-cron@3.0.11': + resolution: {integrity: sha512-0ikrnug3/IyneSHqCBeslAhlK2aBfYek1fGo4bP4QnZPmiqSGRK+Oy7ZMisLWkesffJvQ1cqAcBnJC+8+nxIAg==} + '@types/node-fetch@2.6.11': resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} @@ -10736,6 +10905,10 @@ packages: node-api-version@0.2.0: resolution: {integrity: sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==} + node-cron@3.0.3: + resolution: {integrity: sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==} + engines: {node: '>=6.0.0'} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -14480,6 +14653,161 @@ snapshots: '@gar/promisify@1.1.3': {} + '@hcengineering/account-client@0.7.28': + dependencies: + '@hcengineering/core': 0.7.28 + '@hcengineering/platform': 0.7.28 + + '@hcengineering/analytics@0.7.28': + dependencies: + '@hcengineering/platform': 0.7.28 + + '@hcengineering/card@0.7.28': + dependencies: + '@hcengineering/core': 0.7.28 + '@hcengineering/platform': 0.7.28 + '@hcengineering/ui': 0.7.28 + + '@hcengineering/communication-client-query@0.1.147(typescript@5.3.3)': + dependencies: + '@hcengineering/communication-query': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) + fast-equals: 5.2.2 + typescript: 5.3.3 + + '@hcengineering/communication-cockroach@0.1.147(typescript@5.3.3)': + dependencies: + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-shared': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) + postgres: 3.4.5 + typescript: 5.3.3 + uuid: 11.0.5 + + '@hcengineering/communication-query@0.1.147(typescript@5.3.3)': + dependencies: + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-shared': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-yaml': 0.1.147(typescript@5.3.3) + fast-equals: 5.2.2 + typescript: 5.3.3 + + '@hcengineering/communication-rest-client@0.1.147(typescript@5.3.3)': + dependencies: + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-shared': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) + '@hcengineering/core': 0.7.28 + snappyjs: 0.7.0 + typescript: 5.3.3 + + '@hcengineering/communication-rest-client@0.1.147(typescript@5.7.3)': + dependencies: + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.7.3) + '@hcengineering/communication-shared': 0.1.147(typescript@5.7.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.7.3) + '@hcengineering/core': 0.7.28 + snappyjs: 0.7.0 + typescript: 5.7.3 + + '@hcengineering/communication-sdk-types@0.1.147(typescript@5.3.3)': + dependencies: + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) + '@hcengineering/core': 0.7.28 + typescript: 5.3.3 + + '@hcengineering/communication-sdk-types@0.1.147(typescript@5.7.3)': + dependencies: + '@hcengineering/communication-types': 0.1.147(typescript@5.7.3) + '@hcengineering/core': 0.7.28 + typescript: 5.7.3 + + '@hcengineering/communication-server@0.1.147(typescript@5.3.3)': + dependencies: + '@hcengineering/account-client': 0.7.28 + '@hcengineering/communication-cockroach': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) + '@hcengineering/core': 0.7.28 + '@hcengineering/server-token': 0.7.28 + typescript: 5.3.3 + + '@hcengineering/communication-shared@0.1.147(typescript@5.3.3)': + dependencies: + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) + typescript: 5.3.3 + + '@hcengineering/communication-shared@0.1.147(typescript@5.7.3)': + dependencies: + '@hcengineering/communication-types': 0.1.147(typescript@5.7.3) + typescript: 5.7.3 + + '@hcengineering/communication-types@0.1.147(typescript@5.3.3)': + dependencies: + '@hcengineering/card': 0.7.28 + '@hcengineering/core': 0.7.28 + typescript: 5.3.3 + + '@hcengineering/communication-types@0.1.147(typescript@5.7.3)': + dependencies: + '@hcengineering/card': 0.7.28 + '@hcengineering/core': 0.7.28 + typescript: 5.7.3 + + '@hcengineering/communication-yaml@0.1.147(typescript@5.3.3)': + dependencies: + '@hcengineering/communication-shared': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) + js-yaml: 4.1.0 + typescript: 5.3.3 + + '@hcengineering/communication-yaml@0.1.147(typescript@5.7.3)': + dependencies: + '@hcengineering/communication-shared': 0.1.147(typescript@5.7.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.7.3) + js-yaml: 4.1.0 + typescript: 5.7.3 + + '@hcengineering/core@0.7.28': + dependencies: + '@hcengineering/analytics': 0.7.28 + '@hcengineering/platform': 0.7.28 + fast-equals: 5.2.2 + + '@hcengineering/platform@0.7.28': + dependencies: + intl-messageformat: 10.7.14 + + '@hcengineering/server-token@0.7.28': + dependencies: + '@hcengineering/core': 0.7.28 + '@hcengineering/platform': 0.7.28 + jwt-simple: 0.5.6 + + '@hcengineering/theme@0.7.28': + dependencies: + '@hcengineering/analytics': 0.7.28 + '@hcengineering/platform': 0.7.28 + svelte: 4.2.19 + + '@hcengineering/ui@0.7.28': + dependencies: + '@hcengineering/analytics': 0.7.28 + '@hcengineering/core': 0.7.28 + '@hcengineering/platform': 0.7.28 + '@hcengineering/theme': 0.7.28 + autolinker: 4.0.0 + date-fns: 2.30.0 + date-fns-tz: 2.0.0(date-fns@2.30.0) + dompurify: 3.2.3 + emojibase: 16.0.0 + fast-equals: 5.2.2 + hls.js: 1.5.20 + plyr: 3.7.8 + svelte: 4.2.19 + '@hocuspocus/common@2.11.2': dependencies: lib0: 0.2.89 @@ -15767,6 +16095,7 @@ snapshots: '@rush-temp/activity-resources@file:projects/activity-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) '@types/jest': 29.5.12 '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) @@ -16657,6 +16986,98 @@ snapshots: - supports-color - ts-node + '@rush-temp/chat-assets@file:projects/chat-assets.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': + dependencies: + '@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))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + prettier: 3.2.5 + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + + '@rush-temp/chat-resources@file:projects/chat-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': + dependencies: + '@hcengineering/communication-types': 0.1.147(typescript@5.7.3) + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + eslint-plugin-svelte: 2.35.1(eslint@8.56.0)(svelte@4.2.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + fast-equals: 5.2.2 + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.2(prettier@3.2.5)(svelte@4.2.19) + sass: 1.71.1 + svelte: 4.2.19 + svelte-check: 3.6.9(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.19) + svelte-eslint-parser: 0.33.1(svelte@4.2.19) + svelte-loader: 3.2.0(svelte@4.2.19) + svelte-preprocess: 5.1.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.19)(typescript@5.7.3) + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - coffeescript + - esbuild + - less + - node-notifier + - postcss + - postcss-load-config + - pug + - stylus + - sugarss + - supports-color + - ts-node + + '@rush-temp/chat@file:projects/chat.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': + dependencies: + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + prettier: 3.2.5 + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + '@rush-temp/chunter-assets@file:projects/chunter-assets.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: '@types/jest': 29.5.12 @@ -16752,6 +17173,8 @@ snapshots: '@rush-temp/client-resources@file:projects/client-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) '@types/jest': 29.5.12 '@types/snappyjs': 0.7.1 '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3) @@ -18416,6 +18839,98 @@ snapshots: - supports-color - ts-node + '@rush-temp/inbox-assets@file:projects/inbox-assets.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': + dependencies: + '@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))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + prettier: 3.2.5 + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + + '@rush-temp/inbox-resources@file:projects/inbox-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': + dependencies: + '@hcengineering/communication-types': 0.1.147(typescript@5.7.3) + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + eslint-plugin-svelte: 2.35.1(eslint@8.56.0)(svelte@4.2.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + fast-equals: 5.2.2 + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.2(prettier@3.2.5)(svelte@4.2.19) + sass: 1.71.1 + svelte: 4.2.19 + svelte-check: 3.6.9(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.19) + svelte-eslint-parser: 0.33.1(svelte@4.2.19) + svelte-loader: 3.2.0(svelte@4.2.19) + svelte-preprocess: 5.1.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.19)(typescript@5.7.3) + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - coffeescript + - esbuild + - less + - node-notifier + - postcss + - postcss-load-config + - pug + - stylus + - sugarss + - supports-color + - ts-node + + '@rush-temp/inbox@file:projects/inbox.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': + dependencies: + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + prettier: 3.2.5 + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + '@rush-temp/inventory-assets@file:projects/inventory-assets.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: '@types/jest': 29.5.12 @@ -19128,6 +19643,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@rush-temp/model-chat@file:projects/model-chat.tgz': + dependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + prettier: 3.2.5 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + '@rush-temp/model-chunter@file:projects/model-chunter.tgz': dependencies: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3) @@ -19299,6 +19828,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@rush-temp/model-inbox@file:projects/model-inbox.tgz': + dependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + prettier: 3.2.5 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + '@rush-temp/model-inventory@file:projects/model-inventory.tgz': dependencies: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3) @@ -21346,6 +21889,52 @@ snapshots: - node-notifier - supports-color + '@rush-temp/pod-msg2file@file:projects/pod-msg2file.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))': + dependencies: + '@hcengineering/communication-rest-client': 0.1.147(typescript@5.7.3) + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.7.3) + '@hcengineering/communication-shared': 0.1.147(typescript@5.7.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.7.3) + '@hcengineering/communication-yaml': 0.1.147(typescript@5.7.3) + '@tsconfig/node16': 1.0.4 + '@types/cors': 2.8.17 + '@types/express': 4.17.21 + '@types/jest': 29.5.12 + '@types/js-yaml': 4.0.9 + '@types/node': 20.11.19 + '@types/node-cron': 3.0.11 + '@types/uuid': 8.3.4 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + cors: 2.8.5 + dotenv: 16.0.3 + esbuild: 0.24.2 + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-node: 11.1.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + express: 4.21.2 + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + js-yaml: 4.1.0 + node-cron: 3.0.3 + postgres: 3.4.5 + prettier: 3.2.5 + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + ts-node: 10.9.2(@types/node@20.11.19)(typescript@5.7.3) + typescript: 5.7.3 + uuid: 8.3.2 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@swc/core' + - '@swc/wasm' + - babel-jest + - babel-plugin-macros + - node-notifier + - supports-color + '@rush-temp/pod-print@file:projects/pod-print.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(bufferutil@4.0.8)(utf-8-validate@6.0.4)': dependencies: '@tsconfig/node16': 1.0.4 @@ -21388,6 +21977,7 @@ snapshots: '@rush-temp/pod-server@file:projects/pod-server.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(utf-8-validate@6.0.4)': dependencies: + '@hcengineering/communication-server': 0.1.147(typescript@5.3.3) '@types/jest': 29.5.12 '@types/node': 20.11.19 '@types/ws': 8.5.11 @@ -21834,6 +22424,9 @@ snapshots: '@rush-temp/presentation@file:projects/presentation.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: + '@hcengineering/communication-client-query': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) '@types/jest': 29.5.12 '@types/png-chunks-extract': 1.0.2 '@types/uuid': 8.3.4 @@ -22840,6 +23433,8 @@ snapshots: '@rush-temp/server-activity-resources@file:projects/server-activity-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) '@types/jest': 29.5.12 '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) @@ -23118,6 +23713,7 @@ snapshots: '@rush-temp/server-card-resources@file:projects/server-card-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.7.3) '@types/jest': 29.5.12 '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) @@ -23400,6 +23996,8 @@ snapshots: '@rush-temp/server-core@file:projects/server-core.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) '@types/jest': 29.5.12 '@types/node': 20.11.19 '@types/uuid': 8.3.4 @@ -24742,6 +25340,8 @@ snapshots: '@rush-temp/server@file:projects/server.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: + '@hcengineering/communication-sdk-types': 0.1.147(typescript@5.3.3) + '@hcengineering/communication-types': 0.1.147(typescript@5.3.3) '@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))(eslint@8.56.0)(typescript@5.3.3) @@ -26278,6 +26878,51 @@ snapshots: - supports-color - ts-node + '@rush-temp/ui-next@file:projects/ui-next.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': + dependencies: + '@hcengineering/communication-types': 0.1.147(typescript@5.7.3) + '@tiptap/core': 2.11.3(@tiptap/pm@2.11.3) + '@tiptap/pm': 2.11.3 + '@types/dompurify': 3.0.5 + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + eslint-plugin-svelte: 2.35.1(eslint@8.56.0)(svelte@4.2.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + fast-equals: 5.2.2 + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.2(prettier@3.2.5)(svelte@4.2.19) + sass: 1.71.1 + svelte: 4.2.19 + svelte-check: 3.6.9(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.19) + svelte-eslint-parser: 0.33.1(svelte@4.2.19) + svelte-loader: 3.2.0(svelte@4.2.19) + svelte-preprocess: 5.1.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.19)(typescript@5.7.3) + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - coffeescript + - esbuild + - less + - node-notifier + - postcss + - postcss-load-config + - pug + - stylus + - sugarss + - supports-color + - ts-node + '@rush-temp/ui@file:projects/ui.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(postcss@8.4.35)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: '@types/dompurify': 3.0.5 @@ -27769,6 +28414,8 @@ snapshots: dependencies: '@types/node': 20.11.19 + '@types/node-cron@3.0.11': {} + '@types/node-fetch@2.6.11': dependencies: '@types/node': 20.11.19 @@ -33438,6 +34085,10 @@ snapshots: dependencies: semver: 7.6.3 + node-cron@3.0.3: + dependencies: + uuid: 8.3.2 + node-domexception@1.0.0: {} node-fetch@2.7.0(encoding@0.1.13): diff --git a/desktop/package.json b/desktop/package.json index 46fbe450276..51507a2db04 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -66,6 +66,7 @@ "dependencies": { "@hcengineering/platform": "^0.6.11", "@hcengineering/ui": "^0.6.15", + "@hcengineering/ui-next": "^0.6.0", "@hcengineering/theme": "^0.6.5", "@hcengineering/login": "^0.6.12", "@hcengineering/login-assets": "^0.6.0", @@ -230,6 +231,12 @@ "@hcengineering/mail": "^0.6.0", "@hcengineering/mail-assets": "^0.6.0", "@hcengineering/mail-resources": "^0.6.0", + "@hcengineering/chat": "^0.6.0", + "@hcengineering/chat-assets": "^0.6.0", + "@hcengineering/chat-resources": "^0.6.0", + "@hcengineering/inbox": "^0.6.0", + "@hcengineering/inbox-assets": "^0.6.0", + "@hcengineering/inbox-resources": "^0.6.0", "electron-squirrel-startup": "~1.0.0", "dotenv": "~16.0.0", "electron-context-menu": "^4.0.4", diff --git a/desktop/src/ui/platform.ts b/desktop/src/ui/platform.ts index 1fab0009724..907477a274d 100644 --- a/desktop/src/ui/platform.ts +++ b/desktop/src/ui/platform.ts @@ -56,12 +56,15 @@ import { timeId } from '@hcengineering/time' import tracker, { trackerId } from '@hcengineering/tracker' import { trainingId } from '@hcengineering/training' import uiPlugin, { getCurrentLocation, locationStorageKeyId, navigate, setLocationStorageKey } from '@hcengineering/ui' +import { uiNextId } from '@hcengineering/ui-next' import { uploaderId } from '@hcengineering/uploader' import recorder, { recorderId } from '@hcengineering/recorder' import { viewId } from '@hcengineering/view' import workbench, { workbenchId } from '@hcengineering/workbench' import { mySpaceId } from '@hcengineering/my-space' import { mailId } from '@hcengineering/mail' +import { chatId } from '@hcengineering/chat' +import { inboxId } from '@hcengineering/inbox' import '@hcengineering/activity-assets' import '@hcengineering/analytics-collector-assets' @@ -109,6 +112,8 @@ import '@hcengineering/uploader-assets' import '@hcengineering/view-assets' import '@hcengineering/workbench-assets' import '@hcengineering/mail-assets' +import '@hcengineering/chat-assets' +import '@hcengineering/inbox-assets' import analyticsCollector, { analyticsCollectorId } from '@hcengineering/analytics-collector' import { coreId } from '@hcengineering/core' @@ -147,6 +152,7 @@ function configureI18n (): void { ) addStringsLoader(textEditorId, async (lang: string) => await import(`@hcengineering/text-editor-assets/lang/${lang}.json`)) addStringsLoader(uiId, async (lang: string) => await import(`@hcengineering/ui/lang/${lang}.json`)) + addStringsLoader(uiNextId, async (lang: string) => await import(`@hcengineering/ui-next/lang/${lang}.json`)) addStringsLoader(uploaderId, async (lang: string) => await import(`@hcengineering/uploader-assets/lang/${lang}.json`)) addStringsLoader(recorderId, async (lang: string) => await import(`@hcengineering/recorder-assets/lang/${lang}.json`)) addStringsLoader(activityId, async (lang: string) => await import(`@hcengineering/activity-assets/lang/${lang}.json`)) @@ -217,6 +223,8 @@ function configureI18n (): void { addStringsLoader(cardId, async (lang: string) => await import(`@hcengineering/card-assets/lang/${lang}.json`)) addStringsLoader(mySpaceId, async (lang: string) => await import(`@hcengineering/my-space-assets/lang/${lang}.json`)) addStringsLoader(mailId, async (lang: string) => await import(`@hcengineering/mail-assets/lang/${lang}.json`)) + addStringsLoader(chatId, async (lang: string) => await import(`@hcengineering/chat-assets/lang/${lang}.json`)) + addStringsLoader(inboxId, async (lang: string) => await import(`@hcengineering/inbox-assets/lang/${lang}.json`)) addStringsLoader(processId, async (lang: string) => await import(`@hcengineering/process-assets/lang/${lang}.json`)) } @@ -351,6 +359,8 @@ export async function configurePlatform (): Promise { addLocation(surveyId, () => import(/* webpackChunkName: "survey" */ '@hcengineering/survey-resources')) addLocation(cardId, () => import(/* webpackChunkName: "card" */ '@hcengineering/card-resources')) addLocation(mySpaceId, () => import(/* webpackChunkName: "card" */ '@hcengineering/my-space-resources')) + addLocation(chatId, () => import(/* webpackChunkName: "chat" */ '@hcengineering/chat-resources')) + addLocation(inboxId, () => import(/* webpackChunkName: "inbox" */ '@hcengineering/inbox-resources')) addLocation(processId, () => import(/* webpackChunkName: "process" */ '@hcengineering/process-resources')) setMetadata(client.metadata.FilterModel, 'ui') diff --git a/dev/docker-compose.yaml b/dev/docker-compose.yaml index 05d44afadc6..41df6bdabf1 100644 --- a/dev/docker-compose.yaml +++ b/dev/docker-compose.yaml @@ -347,6 +347,8 @@ services: - LAST_NAME_FIRST=true - BRANDING_PATH=/var/cfg/branding.json - AI_BOT_URL=http://huly.local:4010 + - MSG2FILE_URL=http://huly.local:9087 + - COMMUNICATION_TIME_LOGGING_ENABLED=true restart: unless-stopped rekoni: image: hardcoreeng/rekoni-service @@ -471,24 +473,22 @@ services: - AVATAR_PATH=./avatar.png - AVATAR_CONTENT_TYPE=.png - STATS_URL=http://huly.local:4900 - # - LOVE_ENDPOINT=http://huly.local:8096 - # - OPENAI_API_KEY=token - # telegram-bot: - # image: hardcoreeng/telegram-bot - # extra_hosts: - # - "huly.local:host-gateway" - # restart: unless-stopped - # environment: - # - PORT=4020 - # - QUEUE_CONFIG=${QUEUE_CONFIG} - # - BOT_TOKEN=token - # - MONGO_URL=${MONGO_URL} - # - MONGO_DB=telegram-bot - # - SECRET=secret - # - DOMAIN=domain - # - ACCOUNTS_URL=http://huly.local:3000 - # - SERVICE_ID=telegram-bot-service - # - STATS_URL=http://huly.local:4900 +# - LOVE_ENDPOINT=http://huly.local:8096 +# - OPENAI_API_KEY=token + msg2file: + image: hardcoreeng/msg2file + ports: + - 9087:9087 + extra_hosts: + - 'huly.local:host-gateway' + restart: unless-stopped + environment: + - ACCOUNTS_URL=http://huly.local:3000 + - DB_URL=postgresql://root@huly.local:26257/defaultdb?sslmode=disable + - PORT=9087 + - SECRET=secret + - SERVICE_ID=msg2file-service + - STORAGE_CONFIG=${STORAGE_CONFIG} export: image: hardcoreeng/export extra_hosts: diff --git a/dev/prod/package.json b/dev/prod/package.json index d5a5d55c798..5e711d67b26 100644 --- a/dev/prod/package.json +++ b/dev/prod/package.json @@ -78,6 +78,12 @@ "@hcengineering/card": "^0.6.0", "@hcengineering/card-assets": "^0.6.0", "@hcengineering/card-resources": "^0.6.0", + "@hcengineering/chat": "^0.6.0", + "@hcengineering/chat-assets": "^0.6.0", + "@hcengineering/chat-resources": "^0.6.0", + "@hcengineering/inbox": "^0.6.0", + "@hcengineering/inbox-assets": "^0.6.0", + "@hcengineering/inbox-resources": "^0.6.0", "@hcengineering/chunter": "^0.6.20", "@hcengineering/chunter-assets": "^0.6.18", "@hcengineering/chunter-resources": "^0.6.0", @@ -124,28 +130,6 @@ "@hcengineering/inventory": "^0.6.11", "@hcengineering/inventory-assets": "^0.6.11", "@hcengineering/inventory-resources": "^0.6.0", - "@hcengineering/templates": "^0.6.11", - "@hcengineering/templates-assets": "^0.6.11", - "@hcengineering/templates-resources": "^0.6.0", - "@hcengineering/notification": "^0.6.23", - "@hcengineering/notification-assets": "^0.6.17", - "@hcengineering/notification-resources": "^0.6.0", - "@hcengineering/preference": "^0.6.13", - "@hcengineering/preference-assets": "^0.6.0", - "@hcengineering/rekoni": "^0.6.0", - "@hcengineering/tags-assets": "^0.6.0", - "@hcengineering/tags": "^0.6.16", - "@hcengineering/tags-resources": "^0.6.0", - "@hcengineering/presentation": "^0.6.3", - "@hcengineering/tracker": "^0.6.24", - "@hcengineering/tracker-assets": "^0.6.0", - "@hcengineering/tracker-resources": "^0.6.0", - "@hcengineering/text-editor": "^0.6.0", - "@hcengineering/text-editor-assets": "^0.6.0", - "@hcengineering/text-editor-resources": "^0.6.0", - "@hcengineering/request": "^0.6.14", - "@hcengineering/request-assets": "^0.6.0", - "@hcengineering/request-resources": "^0.6.0", "@hcengineering/lead": "^0.6.0", "@hcengineering/lead-assets": "^0.6.0", "@hcengineering/lead-resources": "^0.6.0", @@ -155,12 +139,24 @@ "@hcengineering/love": "^0.6.0", "@hcengineering/love-assets": "^0.6.0", "@hcengineering/love-resources": "^0.6.0", + "@hcengineering/mail": "^0.6.0", + "@hcengineering/mail-assets": "^0.6.0", + "@hcengineering/mail-resources": "^0.6.0", + "@hcengineering/my-space": "^0.6.0", + "@hcengineering/my-space-assets": "^0.6.0", + "@hcengineering/my-space-resources": "^0.6.0", + "@hcengineering/notification": "^0.6.23", + "@hcengineering/notification-assets": "^0.6.17", + "@hcengineering/notification-resources": "^0.6.0", "@hcengineering/onboard": "^0.6.0", "@hcengineering/onboard-assets": "^0.6.0", "@hcengineering/onboard-resources": "^0.6.0", "@hcengineering/platform": "^0.6.11", + "@hcengineering/preference": "^0.6.13", + "@hcengineering/preference-assets": "^0.6.0", "@hcengineering/presence": "^0.6.0", "@hcengineering/presence-resources": "^0.6.0", + "@hcengineering/presentation": "^0.6.3", "@hcengineering/print": "^0.6.0", "@hcengineering/print-assets": "^0.6.0", "@hcengineering/print-resources": "^0.6.0", @@ -170,9 +166,16 @@ "@hcengineering/questions": "^0.1.0", "@hcengineering/questions-assets": "^0.1.0", "@hcengineering/questions-resources": "^0.1.0", + "@hcengineering/recorder": "^0.6.0", + "@hcengineering/recorder-assets": "^0.6.0", + "@hcengineering/recorder-resources": "^0.6.0", "@hcengineering/recruit": "^0.6.29", "@hcengineering/recruit-assets": "^0.6.23", "@hcengineering/recruit-resources": "^0.6.0", + "@hcengineering/rekoni": "^0.6.0", + "@hcengineering/request": "^0.6.14", + "@hcengineering/request-assets": "^0.6.0", + "@hcengineering/request-resources": "^0.6.0", "@hcengineering/server-activity": "^0.6.0", "@hcengineering/server-activity-resources": "^0.6.0", "@hcengineering/server-attachment": "^0.6.1", @@ -223,35 +226,39 @@ "@hcengineering/survey": "^0.6.0", "@hcengineering/survey-assets": "^0.6.0", "@hcengineering/survey-resources": "^0.6.0", - "@hcengineering/my-space": "^0.6.0", - "@hcengineering/my-space-assets": "^0.6.0", - "@hcengineering/my-space-resources": "^0.6.0", - "@hcengineering/mail": "^0.6.0", - "@hcengineering/mail-assets": "^0.6.0", - "@hcengineering/mail-resources": "^0.6.0", + "@hcengineering/tags": "^0.6.16", + "@hcengineering/tags-assets": "^0.6.0", + "@hcengineering/tags-resources": "^0.6.0", "@hcengineering/task": "^0.6.20", "@hcengineering/task-assets": "^0.6.19", "@hcengineering/task-resources": "^0.6.0", "@hcengineering/telegram": "^0.6.21", "@hcengineering/telegram-assets": "^0.6.0", "@hcengineering/telegram-resources": "^0.6.0", + "@hcengineering/templates": "^0.6.11", + "@hcengineering/templates-assets": "^0.6.11", + "@hcengineering/templates-resources": "^0.6.0", "@hcengineering/test-management": "^0.6.0", "@hcengineering/test-management-assets": "^0.6.0", "@hcengineering/test-management-resources": "^0.6.0", + "@hcengineering/text-editor": "^0.6.0", + "@hcengineering/text-editor-assets": "^0.6.0", + "@hcengineering/text-editor-resources": "^0.6.0", "@hcengineering/theme": "^0.6.5", "@hcengineering/time": "^0.6.0", "@hcengineering/time-assets": "^0.6.0", "@hcengineering/time-resources": "^0.6.0", + "@hcengineering/tracker": "^0.6.24", + "@hcengineering/tracker-assets": "^0.6.0", + "@hcengineering/tracker-resources": "^0.6.0", "@hcengineering/training": "^0.1.0", "@hcengineering/training-assets": "^0.1.0", "@hcengineering/training-resources": "^0.1.0", "@hcengineering/ui": "^0.6.15", + "@hcengineering/ui-next": "^0.6.0", "@hcengineering/uploader": "^0.6.0", "@hcengineering/uploader-assets": "^0.6.0", "@hcengineering/uploader-resources": "^0.6.0", - "@hcengineering/recorder": "^0.6.0", - "@hcengineering/recorder-assets": "^0.6.0", - "@hcengineering/recorder-resources": "^0.6.0", "@hcengineering/view": "^0.6.13", "@hcengineering/view-assets": "^0.6.11", "@hcengineering/view-resources": "^0.6.0", diff --git a/dev/prod/src/platform.ts b/dev/prod/src/platform.ts index a062aa63d6b..5b7e9175b71 100644 --- a/dev/prod/src/platform.ts +++ b/dev/prod/src/platform.ts @@ -64,13 +64,16 @@ import { timeId } from '@hcengineering/time' import tracker, { trackerId } from '@hcengineering/tracker' import { trainingId } from '@hcengineering/training' import uiPlugin from '@hcengineering/ui' +import {uiNextId} from '@hcengineering/ui-next' import { uploaderId } from '@hcengineering/uploader' import recorder, { recorderId } from '@hcengineering/recorder' import { viewId } from '@hcengineering/view' import workbench, { workbenchId } from '@hcengineering/workbench' import { mailId } from '@hcengineering/mail' - +import { chatId } from '@hcengineering/chat' +import github, { githubId } from '@hcengineering/github' import { bitrixId } from '@hcengineering/bitrix' +import {inboxId} from '@hcengineering/inbox' import '@hcengineering/activity-assets' import '@hcengineering/analytics-collector-assets' @@ -119,8 +122,8 @@ import '@hcengineering/uploader-assets' import '@hcengineering/recorder-assets' import '@hcengineering/view-assets' import '@hcengineering/workbench-assets' - -import github, { githubId } from '@hcengineering/github' +import '@hcengineering/chat-assets' +import '@hcengineering/inbox-assets' import '@hcengineering/github-assets' import { coreId } from '@hcengineering/core' @@ -267,6 +270,7 @@ function configureI18n(): void { async (lang: string) => await import(`@hcengineering/text-editor-assets/lang/${lang}.json`) ) addStringsLoader(uiId, async (lang: string) => await import(`@hcengineering/ui/lang/${lang}.json`)) + addStringsLoader(uiNextId, async (lang: string) => await import(`@hcengineering/ui-next/lang/${lang}.json`)) addStringsLoader(uploaderId, async (lang: string) => await import(`@hcengineering/uploader-assets/lang/${lang}.json`)) addStringsLoader(recorderId, async (lang: string) => await import(`@hcengineering/recorder-assets/lang/${lang}.json`)) addStringsLoader(activityId, async (lang: string) => await import(`@hcengineering/activity-assets/lang/${lang}.json`)) @@ -349,7 +353,9 @@ function configureI18n(): void { addStringsLoader(cardId, async (lang: string) => await import(`@hcengineering/card-assets/lang/${lang}.json`)) addStringsLoader(mySpaceId, async (lang: string) => await import(`@hcengineering/my-space-assets/lang/${lang}.json`)) addStringsLoader(mailId, async (lang: string) => await import(`@hcengineering/mail-assets/lang/${lang}.json`)) + addStringsLoader(chatId, async (lang: string) => await import(`@hcengineering/chat-assets/lang/${lang}.json`)) addStringsLoader(processId, async (lang: string) => await import(`@hcengineering/process-assets/lang/${lang}.json`)) + addStringsLoader(inboxId, async (lang: string) => await import(`@hcengineering/inbox-assets/lang/${lang}.json`)) } export async function configurePlatform() { @@ -546,7 +552,9 @@ export async function configurePlatform() { addLocation(cardId, () => import(/* webpackChunkName: "card" */ '@hcengineering/card-resources')) addLocation(mySpaceId, () => import(/* webpackChunkName: "card" */ '@hcengineering/my-space-resources')) addLocation(mailId, () => import(/* webpackChunkName: "card" */ '@hcengineering/mail-resources')) + addLocation(chatId, () => import(/* webpackChunkName: "chat" */ '@hcengineering/chat-resources')) addLocation(processId, () => import(/* webpackChunkName: "process" */ '@hcengineering/process-resources')) + addLocation(inboxId, () => import(/* webpackChunkName: "inbox" */ '@hcengineering/inbox-resources')) setMetadata(client.metadata.FilterModel, 'ui') setMetadata(client.metadata.ExtraPlugins, ['preference' as Plugin]) diff --git a/dev/tool/src/workspace.ts b/dev/tool/src/workspace.ts index cd076722706..b568f72b248 100644 --- a/dev/tool/src/workspace.ts +++ b/dev/tool/src/workspace.ts @@ -15,11 +15,11 @@ // import core, { - DOMAIN_TX, type BackupClient, type Class, type Client as CoreClient, type Doc, + DOMAIN_TX, type MeasureContext, type Ref, type Tx, @@ -32,9 +32,9 @@ import { getMongoClient, getWorkspaceMongoDB } from '@hcengineering/mongo' import { createStorageBackupStorage, restore } from '@hcengineering/server-backup' import { createDummyStorageAdapter, - wrapPipeline, type PipelineFactory, - type StorageAdapter + type StorageAdapter, + wrapPipeline } from '@hcengineering/server-core' import { createStorageFromConfig, storageConfigFromEnv } from '@hcengineering/server-storage' import { connect } from '@hcengineering/server-tool' @@ -164,7 +164,7 @@ export async function backupRestore ( recheck: false, storageAdapter: workspaceStorage, getConnection: async () => { - return wrapPipeline(ctx, await pipelineFactory(ctx, wsUrl, true, () => {}, null), wsUrl) + return wrapPipeline(ctx, await pipelineFactory(ctx, wsUrl, true, () => {}, null, null), wsUrl) } }) ) diff --git a/models/all/package.json b/models/all/package.json index 80c2f39e949..ca0b80c5791 100644 --- a/models/all/package.json +++ b/models/all/package.json @@ -119,7 +119,9 @@ "@hcengineering/model-card": "^0.6.0", "@hcengineering/model-mail": "^0.6.0", "@hcengineering/model-my-space": "^0.6.0", + "@hcengineering/model-chat": "^0.6.0", "@hcengineering/model-process": "^0.6.0", - "@hcengineering/model-server-process": "^0.6.0" + "@hcengineering/model-server-process": "^0.6.0", + "@hcengineering/model-inbox": "^0.6.0" } } diff --git a/models/all/src/index.ts b/models/all/src/index.ts index 1b1a83dc08f..87a5fe3b20f 100644 --- a/models/all/src/index.ts +++ b/models/all/src/index.ts @@ -113,8 +113,9 @@ import { } from '@hcengineering/model-server-controlled-documents' import { surveyId, createModel as surveyModel } from '@hcengineering/model-survey' import { presenceId, createModel as presenceModel } from '@hcengineering/model-presence' +import { chatId, createModel as chatModel } from '@hcengineering/model-chat' import processes, { processId, createModel as processModel } from '@hcengineering/model-process' - +import { createModel as inboxModel, inboxId } from '@hcengineering/model-inbox' import { type Plugin } from '@hcengineering/platform' interface ConfigurablePlugin extends Omit, 'pluginId' | 'transactions'> {} @@ -461,6 +462,8 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[ } ], [mailModel, mailId], + [chatModel, chatId], + [inboxModel, inboxId], [serverCoreModel, serverCoreId], [serverAttachmentModel, serverAttachmentId], diff --git a/models/all/src/migration.ts b/models/all/src/migration.ts index 4786f9cf628..51fed6fe91d 100644 --- a/models/all/src/migration.ts +++ b/models/all/src/migration.ts @@ -56,6 +56,8 @@ import { testManagementOperation } from '@hcengineering/model-test-management' import { surveyOperation } from '@hcengineering/model-survey' import { cardOperation } from '@hcengineering/model-card' import { aiBotId, aiBotOperation } from '@hcengineering/model-ai-bot' +import { chatId, chatOperation } from '@hcengineering/model-chat' +import { inboxId, inboxOperation } from '@hcengineering/model-inbox' export const migrateOperations: [string, MigrateOperation][] = [ ['core', coreOperation], @@ -100,5 +102,7 @@ export const migrateOperations: [string, MigrateOperation][] = [ ['workbench', workbenchOperation], ['testManagement', testManagementOperation], ['survey', surveyOperation], - [aiBotId, aiBotOperation] + [aiBotId, aiBotOperation], + [chatId, chatOperation], + [inboxId, inboxOperation] ] diff --git a/models/chat/.eslintrc.js b/models/chat/.eslintrc.js new file mode 100644 index 00000000000..c1cf82cba08 --- /dev/null +++ b/models/chat/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/model/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/models/chat/.npmignore b/models/chat/.npmignore new file mode 100644 index 00000000000..e3ec093c383 --- /dev/null +++ b/models/chat/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/models/chat/config/rig.json b/models/chat/config/rig.json new file mode 100644 index 00000000000..2f6be366054 --- /dev/null +++ b/models/chat/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "model" +} diff --git a/models/chat/package.json b/models/chat/package.json new file mode 100644 index 00000000000..6e89b06645a --- /dev/null +++ b/models/chat/package.json @@ -0,0 +1,46 @@ +{ + "name": "@hcengineering/model-chat", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "author": "Hardcore Engineering Inc", + "template": "@hcengineering/model-package", + "license": "EPL-2.0", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "_phase:build": "compile transpile src", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "typescript": "^5.3.3" + }, + "dependencies": { + "@hcengineering/card": "^0.6.0", + "@hcengineering/chat": "^0.6.0", + "@hcengineering/chat-resources": "^0.6.0", + "@hcengineering/core": "^0.6.32", + "@hcengineering/model": "^0.6.11", + "@hcengineering/model-card": "^0.6.0", + "@hcengineering/model-core": "^0.6.0", + "@hcengineering/model-view": "^0.6.0", + "@hcengineering/model-workbench": "^0.6.1", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/setting": "^0.6.17", + "@hcengineering/ui": "^0.6.15", + "@hcengineering/view": "^0.6.13", + "@hcengineering/workbench": "^0.6.16" + } +} diff --git a/models/chat/src/index.ts b/models/chat/src/index.ts new file mode 100644 index 00000000000..0179077a708 --- /dev/null +++ b/models/chat/src/index.ts @@ -0,0 +1,137 @@ +// +// Copyright © 2025 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. +// + +import { AccountRole, ClassifierKind, type Ref, SortingOrder } from '@hcengineering/core' +import { type Builder } from '@hcengineering/model' +import core from '@hcengineering/model-core' +import workbench from '@hcengineering/model-workbench' +import { chatId } from '@hcengineering/chat' +import card, { type MasterTag } from '@hcengineering/card' +import setting from '@hcengineering/setting' +import { WidgetType } from '@hcengineering/workbench' +import view from '@hcengineering/model-view' + +import chat from './plugin' + +export { chatId } from '@hcengineering/chat' +export { chatOperation } from './migration' +export default chat + +export function createModel (builder: Builder): void { + builder.createDoc( + workbench.class.Application, + core.space.Model, + { + label: chat.string.Chat, + icon: chat.icon.ChatBubble, + alias: chatId, + accessLevel: AccountRole.User, + hidden: true, + component: chat.component.ChatApplication + }, + chat.app.Chat + ) + + builder.createDoc( + workbench.class.Widget, + core.space.Model, + { + label: chat.string.Chat, + type: WidgetType.Flexible, + icon: chat.icon.ChatBubble, + component: chat.component.ChatWidget + }, + chat.ids.ChatWidget + ) + + builder.createDoc( + card.class.MasterTag, + core.space.Model, + { + extends: card.class.Card, + label: chat.string.Thread, + kind: ClassifierKind.CLASS, + icon: chat.icon.Thread, + pluralLabel: chat.string.Threads + }, + chat.masterTag.Thread + ) + + builder.createDoc( + card.class.MasterTag, + core.space.Model, + { + extends: card.class.Card, + label: chat.string.Channel, + kind: ClassifierKind.CLASS, + icon: chat.icon.Channel, + pluralLabel: chat.string.Channels + }, + chat.masterTag.Channel + ) + + builder.mixin(chat.masterTag.Thread, core.class.Class, setting.mixin.Editable, { + value: true + }) + + builder.mixin(chat.masterTag.Channel, core.class.Class, setting.mixin.Editable, { + value: true + }) + + createViewlet(builder, chat.masterTag.Thread) + createViewlet(builder, chat.masterTag.Channel) +} + +function createViewlet (builder: Builder, type: Ref): void { + builder.createDoc(view.class.Viewlet, core.space.Model, { + attachTo: type, + descriptor: view.viewlet.Table, + configOptions: { + hiddenKeys: ['content', 'title'] + }, + config: [ + '', + '_class', + { key: '', presenter: view.component.RolePresenter, label: card.string.Tags, props: { fullSize: true } }, + 'modifiedOn' + ] + }) + + builder.createDoc(view.class.Viewlet, core.space.Model, { + attachTo: type, + descriptor: view.viewlet.List, + viewOptions: { + groupBy: ['_class', 'createdBy', 'modifiedBy'], + orderBy: [ + ['modifiedOn', SortingOrder.Descending], + ['rank', SortingOrder.Ascending] + ], + other: [] + }, + configOptions: { + hiddenKeys: ['content', 'title'] + }, + config: [ + { key: '', props: { showParent: true } }, + '_class', + { key: '', presenter: view.component.RolePresenter, label: card.string.Tags, props: { fullSize: true } }, + { key: '', displayProps: { grow: true } }, + { + key: 'modifiedOn', + displayProps: { fixed: 'right', dividerBefore: true } + } + ] + }) +} diff --git a/models/chat/src/migration.ts b/models/chat/src/migration.ts new file mode 100644 index 00000000000..6d724e807d1 --- /dev/null +++ b/models/chat/src/migration.ts @@ -0,0 +1,21 @@ +// +// Copyright © 2025 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. +// + +import { type MigrateOperation, type MigrationClient, type MigrationUpgradeClient } from '@hcengineering/model' + +export const chatOperation: MigrateOperation = { + async migrate (client: MigrationClient, mode): Promise {}, + async upgrade (state: Map>, client: () => Promise, mode): Promise {} +} diff --git a/models/chat/src/plugin.ts b/models/chat/src/plugin.ts new file mode 100644 index 00000000000..426232c3b01 --- /dev/null +++ b/models/chat/src/plugin.ts @@ -0,0 +1,26 @@ +// +// Copyright © 2025 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. +// + +import { chatId } from '@hcengineering/chat' +import chat from '@hcengineering/chat-resources/src/plugin' +import { type Ref } from '@hcengineering/core' +import { type Application } from '@hcengineering/model-workbench' +import { mergeIds } from '@hcengineering/platform' + +export default mergeIds(chatId, chat, { + app: { + Chat: '' as Ref + } +}) diff --git a/models/chat/tsconfig.json b/models/chat/tsconfig.json new file mode 100644 index 00000000000..9765b6086db --- /dev/null +++ b/models/chat/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/model/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/models/inbox/.eslintrc.js b/models/inbox/.eslintrc.js new file mode 100644 index 00000000000..c1cf82cba08 --- /dev/null +++ b/models/inbox/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/model/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/models/inbox/.npmignore b/models/inbox/.npmignore new file mode 100644 index 00000000000..e3ec093c383 --- /dev/null +++ b/models/inbox/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/models/inbox/config/rig.json b/models/inbox/config/rig.json new file mode 100644 index 00000000000..2f6be366054 --- /dev/null +++ b/models/inbox/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "model" +} diff --git a/models/inbox/package.json b/models/inbox/package.json new file mode 100644 index 00000000000..020e8c427ff --- /dev/null +++ b/models/inbox/package.json @@ -0,0 +1,44 @@ +{ + "name": "@hcengineering/model-inbox", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "author": "Hardcore Engineering Inc", + "template": "@hcengineering/model-package", + "license": "EPL-2.0", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "_phase:build": "compile transpile src", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "typescript": "^5.3.3" + }, + "dependencies": { + "@hcengineering/card": "^0.6.0", + "@hcengineering/inbox": "^0.6.0", + "@hcengineering/inbox-resources": "^0.6.0", + "@hcengineering/core": "^0.6.32", + "@hcengineering/model": "^0.6.11", + "@hcengineering/model-core": "^0.6.0", + "@hcengineering/model-workbench": "^0.6.1", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/setting": "^0.6.17", + "@hcengineering/ui": "^0.6.15", + "@hcengineering/view": "^0.6.13", + "@hcengineering/workbench": "^0.6.16" + } +} diff --git a/models/inbox/src/index.ts b/models/inbox/src/index.ts new file mode 100644 index 00000000000..a6d75a75736 --- /dev/null +++ b/models/inbox/src/index.ts @@ -0,0 +1,42 @@ +// +// Copyright © 2025 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. +// + +import { AccountRole } from '@hcengineering/core' +import { type Builder } from '@hcengineering/model' +import core from '@hcengineering/model-core' +import workbench from '@hcengineering/model-workbench' +import { inboxId } from '@hcengineering/inbox' + +import inbox from './plugin' + +export { inboxId } from '@hcengineering/inbox' +export { inboxOperation } from './migration' +export default inbox + +export function createModel (builder: Builder): void { + builder.createDoc( + workbench.class.Application, + core.space.Model, + { + label: inbox.string.Inbox, + icon: inbox.icon.Inbox, + alias: inboxId, + accessLevel: AccountRole.User, + hidden: true, + component: inbox.component.InboxApplication + }, + inbox.app.Inbox + ) +} diff --git a/models/inbox/src/migration.ts b/models/inbox/src/migration.ts new file mode 100644 index 00000000000..ab4d876d36b --- /dev/null +++ b/models/inbox/src/migration.ts @@ -0,0 +1,21 @@ +// +// Copyright © 2025 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. +// + +import { type MigrateOperation, type MigrationClient, type MigrationUpgradeClient } from '@hcengineering/model' + +export const inboxOperation: MigrateOperation = { + async migrate (client: MigrationClient, mode): Promise {}, + async upgrade (state: Map>, client: () => Promise, mode): Promise {} +} diff --git a/models/inbox/src/plugin.ts b/models/inbox/src/plugin.ts new file mode 100644 index 00000000000..f3cf60aa6b9 --- /dev/null +++ b/models/inbox/src/plugin.ts @@ -0,0 +1,26 @@ +// +// Copyright © 2025 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. +// + +import { inboxId } from '@hcengineering/inbox' +import inbox from '@hcengineering/inbox-resources/src/plugin' +import { type Ref } from '@hcengineering/core' +import { type Application } from '@hcengineering/model-workbench' +import { mergeIds } from '@hcengineering/platform' + +export default mergeIds(inboxId, inbox, { + app: { + Inbox: '' as Ref + } +}) diff --git a/models/inbox/tsconfig.json b/models/inbox/tsconfig.json new file mode 100644 index 00000000000..9765b6086db --- /dev/null +++ b/models/inbox/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/model/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/models/server-activity/package.json b/models/server-activity/package.json index 2b688ba63a7..8284eb505a2 100644 --- a/models/server-activity/package.json +++ b/models/server-activity/package.json @@ -30,6 +30,7 @@ "dependencies": { "@hcengineering/activity": "^0.6.0", "@hcengineering/core": "^0.6.32", + "@hcengineering/card": "^0.6.0", "@hcengineering/model": "^0.6.11", "@hcengineering/model-activity": "^0.6.0", "@hcengineering/platform": "^0.6.11", diff --git a/models/server-activity/src/index.ts b/models/server-activity/src/index.ts index 2db04c9db1b..fa0ffedf3c2 100644 --- a/models/server-activity/src/index.ts +++ b/models/server-activity/src/index.ts @@ -20,6 +20,7 @@ import serverActivity from '@hcengineering/server-activity' import serverNotification from '@hcengineering/server-notification' import activity from '@hcengineering/activity' import notification from '@hcengineering/notification' +import card from '@hcengineering/card' export { activityServerOperation } from './migration' export { serverActivityId } from '@hcengineering/server-activity' @@ -49,6 +50,14 @@ export function createModel (builder: Builder): void { isAsync: true }) + builder.createDoc(serverCore.class.Trigger, core.space.Model, { + trigger: serverActivity.trigger.HandleCardActivity, + isAsync: true, + txMatch: { + objectClass: card.class.Card + } + }) + builder.createDoc(serverCore.class.Trigger, core.space.Model, { trigger: serverActivity.trigger.OnDocRemoved }) diff --git a/packages/account-client/src/client.ts b/packages/account-client/src/client.ts index fd37f48294f..e12767b4805 100644 --- a/packages/account-client/src/client.ts +++ b/packages/account-client/src/client.ts @@ -89,8 +89,8 @@ export interface AccountClient { updateWorkspaceRole: (account: string, role: AccountRole) => Promise updateWorkspaceName: (name: string) => Promise deleteWorkspace: () => Promise - findPersonBySocialKey: (socialKey: string) => Promise - findPersonBySocialId: (socialId: PersonId) => Promise + findPersonBySocialKey: (socialKey: string, requireAccount?: boolean) => Promise + findPersonBySocialId: (socialId: PersonId, requireAccount?: boolean) => Promise findSocialIdBySocialKey: (socialKey: string) => Promise getMailboxOptions: () => Promise createMailbox: (name: string, domain: string) => Promise @@ -554,19 +554,19 @@ class AccountClientImpl implements AccountClient { await this.rpc(request) } - async findPersonBySocialKey (socialString: string): Promise { + async findPersonBySocialKey (socialString: string, requireAccount?: boolean): Promise { const request = { method: 'findPersonBySocialKey' as const, - params: { socialString } + params: { socialString, requireAccount } } return await this.rpc(request) } - async findPersonBySocialId (socialId: PersonId): Promise { + async findPersonBySocialId (socialId: PersonId, requireAccount?: boolean): Promise { const request = { method: 'findPersonBySocialId' as const, - params: { socialId } + params: { socialId, requireAccount } } return await this.rpc(request) diff --git a/packages/api-client/package.json b/packages/api-client/package.json index f6ab73b269b..a5871cf2164 100644 --- a/packages/api-client/package.json +++ b/packages/api-client/package.json @@ -50,11 +50,11 @@ "@types/snappyjs": "^0.7.1" }, "dependencies": { - "@hcengineering/core": "^0.6.32", + "@hcengineering/account-client": "^0.6.0", "@hcengineering/client": "^0.6.18", "@hcengineering/client-resources": "^0.6.27", "@hcengineering/collaborator-client": "^0.6.4", - "@hcengineering/account-client": "^0.6.0", + "@hcengineering/core": "^0.6.32", "@hcengineering/platform": "^0.6.11", "@hcengineering/text": "^0.6.5", "@hcengineering/text-markdown": "^0.6.0", diff --git a/packages/api-client/src/rest/rest.ts b/packages/api-client/src/rest/rest.ts index fb2995eb9cf..cd9431132cf 100644 --- a/packages/api-client/src/rest/rest.ts +++ b/packages/api-client/src/rest/rest.ts @@ -15,7 +15,9 @@ import { type Account, + buildModel, type Class, + concatLink, type Doc, type DocumentQuery, type FindOptions, @@ -29,11 +31,8 @@ import { type SearchResult, type Tx, type TxResult, - type WithLookup, - buildModel, - concatLink + type WithLookup } from '@hcengineering/core' - import { PlatformError, unknownError } from '@hcengineering/platform' import type { RestClient } from './types' diff --git a/packages/core/src/__tests__/client.test.ts b/packages/core/src/__tests__/client.test.ts index 13f2ac36f98..9158e8e227b 100644 --- a/packages/core/src/__tests__/client.test.ts +++ b/packages/core/src/__tests__/client.test.ts @@ -121,6 +121,7 @@ describe('client', () => { isConnected = (): boolean => true findAll = findAll + pushHandler = (): void => {} searchFulltext = async (query: SearchQuery, options: SearchOptions): Promise => { return { docs: [] } diff --git a/packages/core/src/__tests__/connection.ts b/packages/core/src/__tests__/connection.ts index a9a831b81f9..4f3caaab5ab 100644 --- a/packages/core/src/__tests__/connection.ts +++ b/packages/core/src/__tests__/connection.ts @@ -64,6 +64,8 @@ export async function connect (handler: (tx: Tx) => void): Promise {} + async tx (tx: Tx): Promise { if (tx.objectSpace === core.space.Model) { hierarchy.tx(tx) diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 5136173e66e..ff866368b15 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -43,6 +43,7 @@ export interface Client extends Storage, FulltextStorage { options?: FindOptions ) => Promise | undefined> close: () => Promise + getConnection?: () => ClientConnection } /** @@ -69,6 +70,9 @@ export enum ClientConnectEvent { Refresh, // In case we detect query refresh is required Maintenance // In case workspace are in maintenance mode } + +export type Handler = (...result: any[]) => void + /** * @public */ @@ -82,6 +86,7 @@ export interface ClientConnection extends Storage, FulltextStorage, BackupClient loadModel: (last: Timestamp, hash?: string) => Promise getLastHash?: (ctx: MeasureContext) => Promise + pushHandler: (handler: Handler) => void } class ClientImpl implements Client, BackupClient { @@ -91,6 +96,10 @@ class ClientImpl implements Client, BackupClient { private readonly appliedModelTransactions = new Set>() constructor (private readonly conn: ClientConnection) {} + getConnection (): ClientConnection { + return this.conn + } + setModel (hierarchy: Hierarchy, model: ModelDb): void { this.hierarchy = hierarchy this.model = model diff --git a/packages/core/src/operations.ts b/packages/core/src/operations.ts index 5c0af58b314..516d376c247 100644 --- a/packages/core/src/operations.ts +++ b/packages/core/src/operations.ts @@ -35,7 +35,7 @@ import { DocumentClassQuery, Tx, TxApplyResult, TxCUD, TxFactory, TxProcessor } * * `notify` is not supported by TxOperations. */ -export class TxOperations implements Omit { +export class TxOperations implements Omit { readonly txFactory: TxFactory constructor ( diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 89ef9dcdafc..f9cbf42e99c 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -890,14 +890,20 @@ export class TimeRateLimiter { export function combineAttributes ( attributes: any[], key: string, - operator: '$push' | '$pull', - arrayKey: '$each' | '$in' + operator: '$push' | '$pull' | '$unset', + arrayKey?: '$each' | '$in' ): any[] { return Array.from( new Set( - attributes.flatMap((attr) => - Array.isArray(attr[operator]?.[key]?.[arrayKey]) ? attr[operator]?.[key]?.[arrayKey] : attr[operator]?.[key] - ) + attributes.flatMap((attr) => { + if (arrayKey === undefined) { + return attr[operator]?.[key] + } + + return Array.isArray(attr[operator]?.[key]?.[arrayKey]) + ? attr[operator]?.[key]?.[arrayKey] + : attr[operator]?.[key] + }) ) ).filter((v) => v != null) } diff --git a/packages/panel/src/components/Panel.svelte b/packages/panel/src/components/Panel.svelte index 53d931e9133..df93b562af8 100644 --- a/packages/panel/src/components/Panel.svelte +++ b/packages/panel/src/components/Panel.svelte @@ -63,6 +63,7 @@ export let hideActions: boolean = false export let hideExtra: boolean = false export let overflowExtra: boolean = false + export let newActivity: boolean = false const account = getCurrentAccount() $: isGuest = account.role === AccountRole.DocGuest @@ -303,7 +304,7 @@ {#if showActivity} {#key object._id} Promise + findMessagesGroups: (params: FindMessagesGroupsParams) => Promise + findNotificationContexts: (params: FindNotificationContextParams, queryId?: number) => Promise + findNotifications: (params: FindNotificationsParams, queryId?: number) => Promise + sendEvent: (event: RequestEvent) => Promise + unsubscribeQuery: (id: number) => Promise +} + +let client: CommunicationClient + +export type CommunicationClient = Client + +export function getCommunicationClient (): CommunicationClient { + return client +} + +export async function setCommunicationClient (platformClient: PlatformClient, socialIds: SocialId[]): Promise { + const connection = platformClient.getConnection?.() + if (connection === undefined) { + return + } + client = new Client(connection as unknown as Connection, socialIds) + initLiveQueries(client, getCurrentWorkspaceUuid(), getFilesUrl(), onDestroy) +} + +class Client { + private readonly hulySocialId: SocialId | undefined + + constructor ( + private readonly connection: Connection, + socialIds: SocialId[] + ) { + this.hulySocialId = socialIds.find((it) => it.type === SocialIdType.HULY && it.verifiedOn !== undefined) + + connection.pushHandler((...events: any[]) => { + for (const event of events) { + if (event != null && 'type' in event) { + this.onEvent(event as ResponseEvent) + } + } + }) + } + + onEvent: (event: ResponseEvent) => void = () => {} + onRequest: (event: RequestEvent, eventPromise: Promise) => void = () => {} + + async createThread (card: CardID, message: MessageID, thread: CardID): Promise { + const event: CreateThreadEvent = { + type: RequestEventType.CreateThread, + card, + message, + thread + } + + await this.sendEvent(event) + } + + async createMessage (card: CardID, content: RichText): Promise { + const event: CreateMessageEvent = { + type: RequestEventType.CreateMessage, + messageType: MessageType.Message, + card, + content, + creator: this.getSocialId() + } + const result = await this.sendEvent(event) + return (result as CreateMessageResult).id + } + + async updateMessage (card: CardID, message: MessageID, content: RichText): Promise { + const event: CreatePatchEvent = { + type: RequestEventType.CreatePatch, + patchType: PatchType.update, + card, + message, + content, + creator: this.getSocialId() + } + await this.sendEvent(event) + } + + async createReaction (card: CardID, message: MessageID, reaction: string): Promise { + const event: CreateReactionEvent = { + type: RequestEventType.CreateReaction, + card, + message, + reaction, + creator: this.getSocialId() + } + await this.sendEvent(event) + } + + async removeReaction (card: CardID, message: MessageID, reaction: string): Promise { + const event: RemoveReactionEvent = { + type: RequestEventType.RemoveReaction, + card, + message, + reaction, + creator: this.getSocialId() + } + await this.sendEvent(event) + } + + async createFile ( + card: CardID, + message: MessageID, + blobId: BlobID, + fileType: string, + filename: string, + size: number + ): Promise { + const event: CreateFileEvent = { + type: RequestEventType.CreateFile, + card, + message, + blobId, + fileType, + filename, + size, + creator: this.getSocialId() + } + await this.sendEvent(event) + } + + async removeFile (card: CardID, message: MessageID, blobId: BlobID): Promise { + const event: RemoveFileEvent = { + type: RequestEventType.RemoveFile, + card, + message, + blobId, + creator: this.getSocialId() + } + await this.sendEvent(event) + } + + async updateNotificationContext (context: ContextID, lastView?: Date): Promise { + const event: UpdateNotificationContextEvent = { + type: RequestEventType.UpdateNotificationContext, + context, + account: this.getAccount(), + lastView + } + await this.sendEvent(event) + } + + async findMessages (params: FindMessagesParams, queryId?: number): Promise { + return await this.connection.findMessages(params, queryId) + } + + async findMessagesGroups (params: FindMessagesGroupsParams): Promise { + return await this.connection.findMessagesGroups(params) + } + + async findNotificationContexts ( + params: FindNotificationContextParams, + queryId?: number + ): Promise { + return await this.connection.findNotificationContexts(params, queryId) + } + + async findNotifications (params: FindNotificationsParams, queryId?: number): Promise { + return await this.connection.findNotifications(params, queryId) + } + + async unsubscribeQuery (id: number): Promise { + await this.connection.unsubscribeQuery(id) + } + + close (): void { + // do nothing + } + + private async sendEvent (event: RequestEvent): Promise { + const ev: RequestEvent = { ...event, _id: generateId() } + const eventPromise = this.connection.sendEvent(ev) + this.onRequest(ev, eventPromise) + return await eventPromise + } + + private getSocialId (): SocialID { + const me = getCurrentAccount() + const id = this.hulySocialId?._id ?? me.primarySocialId + if (id == null || id === '') { + throw new Error('Social id not found') + } + return id + } + + private getAccount (): AccountID { + return getCurrentAccount().uuid + } +} diff --git a/packages/presentation/src/file.ts b/packages/presentation/src/file.ts index c2ae14b8971..2b885116d8a 100644 --- a/packages/presentation/src/file.ts +++ b/packages/presentation/src/file.ts @@ -92,7 +92,7 @@ export function parseUploadConfig (config: string, uploadUrl: string): UploadCon return uploadConfig } -function getFilesUrl (): string { +export function getFilesUrl (): string { const filesUrl = getMetadata(plugin.metadata.FilesURL) ?? defaultFilesUrl const frontUrl = getMetadata(plugin.metadata.FrontUrl) ?? window.location.origin diff --git a/packages/presentation/src/index.ts b/packages/presentation/src/index.ts index baefdbb1c16..4452d4c2327 100644 --- a/packages/presentation/src/index.ts +++ b/packages/presentation/src/index.ts @@ -71,3 +71,4 @@ export * from './sound' export * from './stats' export * from './drawing' export * from './link-preview' +export * from './communication' diff --git a/packages/query/src/__tests__/connection.ts b/packages/query/src/__tests__/connection.ts index f6c154aebb5..b09e3894d93 100644 --- a/packages/query/src/__tests__/connection.ts +++ b/packages/query/src/__tests__/connection.ts @@ -28,6 +28,7 @@ import core, { FindResult, FulltextStorage, generateId, + Handler, Hierarchy, LoadModelResponse, ModelDb, @@ -48,6 +49,7 @@ BackupClient & FulltextStorage & { isConnected: () => boolean loadModel: (last: Timestamp, hash?: string) => Promise + pushHandler: (handler: Handler) => void } > { const txes = genMinModel() @@ -77,6 +79,8 @@ FulltextStorage & { return true } + pushHandler (): void {} + async findAll( _class: Ref>, query: DocumentQuery, diff --git a/packages/theme/styles/_next-colors.scss b/packages/theme/styles/_next-colors.scss new file mode 100644 index 00000000000..2bd400e2608 --- /dev/null +++ b/packages/theme/styles/_next-colors.scss @@ -0,0 +1,168 @@ +// +// © 2025 Hardcore Engineering, Inc. All Rights Reserved. +// Licensed under the Eclipse Public License v2.0 (SPDX: EPL-2.0). +// + +* { + --color-global-white-100: #FFFFFF; + --color-global-white-50: rgba(255, 255, 255, 0.5); + --color-global-white-0: rgba(255, 255, 255, 0); + + --color-global-black-100: #000000; + --color-global-black-50: rgba(0, 0, 0, 0.5); + --color-global-black-0: rgba(0, 0, 0, 0); + + --color-global-steel-blue: #4882B9; + --color-global-sky-blue: #3496F2; + --color-global-royal-blue: #1E77F4; + + --color-global-bright-orange: #FF4000; + --color-global-bright-green: #0AB76C; + + --color-global-light-gray: #FBFBFB; + --color-global-mist-100: #F0EEEE; + --color-global-mist-70: rgba(240, 238, 238, 0.7); + --color-global-mist-0: rgba(240, 238, 238, 0); + + --color-global-onyx-100: #252529; + --color-global-onyx-70: rgba(37, 37, 41, 0.7); + --color-global-onyx-0: rgba(37, 37, 41, 0); + + --color-global-dark-gray: #1C1C1D; + --color-global-charcoal-black: #19191C; + + --color-huly-off-white-100: #E3E3E3; + --color-huly-off-white-85: rgba(227, 227, 227, 0.85); + --color-huly-off-white-75: rgba(227, 227, 227, 0.75); + --color-huly-off-white-50: rgba(227, 227, 227, 0.5); + --color-huly-off-white-25: rgba(227, 227, 227, 0.25); + --color-huly-off-white-15: rgba(227, 227, 227, 0.15); + --color-huly-off-white-10: rgba(227, 227, 227, 0.1); + --color-huly-off-white-5: rgba(227, 227, 227, 0.05); + --color-huly-off-white-0: rgba(227, 227, 227, 0); + + --color-huly-dark-grey-100: #36373D; + --color-huly-dark-grey-85: rgba(54, 55, 61, 0.85); + --color-huly-dark-grey-75: rgba(54, 55, 61, 0.75); + --color-huly-dark-grey-50: rgba(54, 55, 61, 0.5); + --color-huly-dark-grey-25: rgba(54, 55, 61, 0.25); + --color-huly-dark-grey-15: rgba(54, 55, 61, 0.15); + --color-huly-dark-grey-10: rgba(54, 55, 61, 0.1); + --color-huly-dark-grey-5: rgba(54, 55, 61, 0.05); + --color-huly-dark-grey-0: rgba(54, 55, 61, 0); +} + +/* Dark Theme */ +.theme-dark { + --next-background-color: var(--next-surface-color-bg-1); + --next-border-color: var(--next-divider-color); + + //Panel + --next-panel-color-background: var(--next-surface-color-bg-2); + --next-panel-color-border: var(--next-divider-color); + + //Surface + --next-surface-color-bg-1: var(--color-global-charcoal-black); + --next-surface-color-bg-inv-1: var(--color-global-white-100); + --next-surface-color-bg-2: var(--color-global-onyx-100); + --next-surface-color-bg-inv-2: var(--color-global-mist-100); + --next-surface-color-fg: var(--color-huly-off-white-75); + --next-surface-color-fg-inv: var(--color-huly-dark-grey-75); + + //Divider + --next-divider-color: var(--color-huly-off-white-15); + + //Text + --next-text-color-primary: var(--color-huly-off-white-100); + --next-text-color-primary-inverted: var(--color-huly-dark-grey-100); + --next-text-color-secondary: var(--color-huly-off-white-85); + --next-text-color-secondary-inverted: var(--color-huly-dark-grey-85); + --next-text-color-tertiary: var(--color-huly-off-white-50); + --next-text-color-tertiary-inverted: var(--color-huly-dark-grey-50); + + //Label + --next-label-color-primary: var(--color-huly-off-white-100); + --next-label-color-secondary: var(--color-huly-off-white-85); + --next-label-color-tertiary: var(--color-huly-off-white-50); + + //Reaction + --next-reaction-counter-rest-color-background: var(--color-huly-off-white-5); + --next-reaction-counter-rest-color-foreground: var(--color-huly-off-white-85); + --next-reaction-counter-rest-color-label: var(--color-huly-off-white-100); + --next-reaction-counter-hover-color-background: var(--color-huly-off-white-10); + --next-reaction-counter-selected-color-background: var(--color-global-royal-blue); + + //ButtonMenu background + --next-button-menu-ghost-background-color-rest: var(--color-global-white-0); + --next-button-menu-ghost-background-color-hover: var(--color-huly-off-white-10); + --next-button-menu-ghost-background-color-active: var(--color-huly-off-white-25); + --next-button-menu-ghost-background-color-disabled: var(--color-global-white-0); + + //ButtonMenu foreground + --next-button-menu-ghost-foreground-color-rest: var(--color-huly-off-white-85); + --next-button-menu-ghost-foreground-color-hover: var(--color-huly-off-white-100); + --next-button-menu-ghost-foreground-color-active: var(--color-huly-off-white-100); + --next-button-menu-ghost-foreground-color-disabled: var(--color-huly-off-white-25); + + //MessageInput + --next-message-input-color-background: var(--color-global-dark-gray); + --next-message-input-color-stroke: var(--color-global-charcoal-black); +} + + +/* Light Theme */ +.theme-light { + --next-background-color: var(--next-surface-color-bg-1); + --next-border-color: var(--next-divider-color); + + //Panel + --next-panel-color-background: var(--next-surface-color-bg-2); + --next-panel-color-border: var(--next-divider-color); + + //Surface + --next-surface-color-bg-1: var(--color-global-white-100); + --next-surface-color-bg-inv-1: var(--color-global-charcoal-black); + --next-surface-color-bg-2: var(--color-global-mist-100); + --next-surface-color-bg-inv-2: var(--color-global-onyx-100); + --next-surface-color-fg: var(--color-huly-dark-grey-75); + --next-surface-color-fg-inv: var(--color-huly-off-white-75); + + //Divider + --next-divider-color: var(--color-huly-dark-grey-15); + + //Text + --next-text-color-primary: var(--color-huly-dark-grey-100); + --next-text-color-primary-inverted: var(--color-huly-off-white-100); + --next-text-color-secondary: var(--color-huly-dark-grey-85); + --next-text-color-secondary-inverted: var(--color-huly-off-white-85); + --next-text-color-tertiary: var(--color-huly-dark-grey-50); + --next-text-color-tertiary-inverted: var(--color-huly-off-white-50); + + //Label + --next-label-color-primary: var(--color-huly-dark-grey-100); + --next-label-color-secondary: var(--color-huly-dark-grey-85); + --next-label-color-tertiary: var(--color-huly-dark-grey-50); + + //Reaction + --next-reaction-counter-rest-color-background: var(--color-huly-dark-grey-5); + --next-reaction-counter-rest-color-foreground: var(--color-huly-dark-grey-85); + --next-reaction-counter-rest-color-label: var(--color-huly-dark-grey-100); + --next-reaction-counter-hover-color-background: var(--color-huly-dark-grey-10); + --next-reaction-counter-selected-color-background: var(--color-global-royal-blue); + + //ButtonMenu background + --next-button-menu-ghost-background-color-rest: var(--color-global-white-0); + --next-button-menu-ghost-background-color-hover: var(--color-huly-dark-grey-10); + --next-button-menu-ghost-background-color-active: var(--color-huly-dark-grey-25); + --next-button-menu-ghost-background-color-disabled: var(--color-global-white-0); + + //ButtonMenu foreground + --next-button-menu-ghost-foreground-color-rest: var(--color-huly-dark-grey-85); + --next-button-menu-ghost-foreground-color-hover: var(--color-huly-dark-grey-100); + --next-button-menu-ghost-foreground-color-active: var(--color-huly-dark-grey-100); + --next-button-menu-ghost-foreground-color-disabled: var(--color-huly-dark-grey-25); + + //MessageInput + --next-message-input-color-background: var(--color-global-light-gray); + --next-message-input-color-stroke: var(--color-global-white-100); +} diff --git a/packages/theme/styles/_next-vars.scss b/packages/theme/styles/_next-vars.scss new file mode 100644 index 00000000000..6c432509589 --- /dev/null +++ b/packages/theme/styles/_next-vars.scss @@ -0,0 +1,25 @@ +// +// Copyright © 2021 Anticrm Platform Contributors. +// +// 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. +// + +* { + --next-avatar-size-xsmall: 1.5rem; /* 24px */ + --next-avatar-size-small: 2rem; /* 32px */ + --next-avatar-size-regular: 2.25rem; /* 36px */ + --next-avatar-size-medium: 2.5rem; /* 40px */ + --next-avatar-size-large: 3rem; /* 48px */ + --next-avatar-size-xlarge: 4rem; /* 64px */ + --next-avatar-size-xxlarge: 5rem; /* 80px */ + --next-avatar-size-xxxlarge: 8rem; /* 128px */ +} diff --git a/packages/theme/styles/global.scss b/packages/theme/styles/global.scss index 1cfe1d7364c..6a070bf27cb 100644 --- a/packages/theme/styles/global.scss +++ b/packages/theme/styles/global.scss @@ -29,10 +29,13 @@ @import "./prose.scss"; @import "./tables.scss"; @import "./_text-editor.scss"; +@import "./_next-colors.scss"; +@import "./_next-vars.scss"; @import "./love.scss"; @import "./mono.scss"; +@import "./next-ui.scss"; @font-face { font-family: 'IBM Plex Sans'; diff --git a/packages/theme/styles/next-ui.scss b/packages/theme/styles/next-ui.scss new file mode 100644 index 00000000000..6221fe9af1d --- /dev/null +++ b/packages/theme/styles/next-ui.scss @@ -0,0 +1,55 @@ +.next-svg__xx-small { + width: .75rem; + height: .75rem; +} + +.next-svg__x-small { + width: .875rem; + height: .875rem; +} + +.next-svg__small { + width: 1rem; + height: 1rem; +} + +.next-svg__medium { + width: 1.25rem; + height: 1.25rem; +} + +.next-svg__large { + width: 1.5rem; + height: 1.5rem; +} + +.next-label-overflow { + white-space: nowrap; + word-break: break-all; + text-overflow: ellipsis; + overflow: hidden; + min-width: 0; +} + +.next-text-editor-view { + color: var(--next-text-color-primary); + margin: 0; + p.is-editor-empty:first-child::before { + content: attr(data-placeholder); + float: left; + color: var(--next-text-color-tertiary); + pointer-events: none; + height: 0; + } + + &:focus-within p.is-editor-empty:first-child::before { + color: var(--next-text-color-tertiary); + } +} + + +.next-colors { + p.contrast { + color: var(--next-text-color-primary) !important; + } +} diff --git a/packages/ui-next/.eslintrc.js b/packages/ui-next/.eslintrc.js new file mode 100644 index 00000000000..bb8fd7450d4 --- /dev/null +++ b/packages/ui-next/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/ui/eslint.config.json'], + parserOptions: { tsconfigRootDir: __dirname } +} diff --git a/packages/ui-next/.prettierrc b/packages/ui-next/.prettierrc new file mode 100644 index 00000000000..792942803ac --- /dev/null +++ b/packages/ui-next/.prettierrc @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "trailingComma": "none", + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "printWidth": 120, + "useTabs": false, + "bracketSpacing": true, + "proseWrap": "preserve", + "plugins": [ + "prettier-plugin-svelte" + ], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} \ No newline at end of file diff --git a/packages/ui-next/config/rig.json b/packages/ui-next/config/rig.json new file mode 100644 index 00000000000..1a4b944f834 --- /dev/null +++ b/packages/ui-next/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "ui" +} diff --git a/packages/ui-next/jest.config.js b/packages/ui-next/jest.config.js new file mode 100644 index 00000000000..3656e284d33 --- /dev/null +++ b/packages/ui-next/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'] +} diff --git a/packages/ui-next/lang/cs.json b/packages/ui-next/lang/cs.json new file mode 100644 index 00000000000..ae7d1e77039 --- /dev/null +++ b/packages/ui-next/lang/cs.json @@ -0,0 +1,30 @@ +{ + "string": { + "Added": "Přidáno", + "Attach": "Připojit", + "Cancel": "Zrušit", + "Edit": "Upravit", + "Edited": "Upraveno", + "Emoji": "Emoji", + "HoursAgo": "{hours, plural, =0 {před méně než hodinou} =1 {před hodinou} other {před {#} hodinami}}", + "JustNow": "Právě teď", + "LastReply": "Poslední odpověď", + "Mention": "Zmínit", + "MinutesAgo": "{minutes, plural, =0 {před méně než minutou} =1 {před minutou} other {před {#} minutami}}", + "MonthAt": "{month} v {time}", + "New": "Nový", + "Removed": "Odstraněno", + "RepliesCount": "{count} odpovědí", + "Reply": "Odpovědět", + "Send": "Odeslat", + "Set": "Nastavit", + "ShowFormatting": "Zobrazit formátování", + "To": "Do", + "Today": "Dnes", + "Unset": "Zrušit", + "WeekdayAt": "{weekday} v {time}", + "YearAt": "{year} v {time}", + "Yesterday": "Včera", + "YesterdayAt": "Včera v {time}" + } +} diff --git a/packages/ui-next/lang/de.json b/packages/ui-next/lang/de.json new file mode 100644 index 00000000000..8f1a6168150 --- /dev/null +++ b/packages/ui-next/lang/de.json @@ -0,0 +1,30 @@ +{ + "string": { + "Added": "Hinzugefügt", + "Attach": "Anhängen", + "Cancel": "Abbrechen", + "Edit": "Bearbeiten", + "Edited": "Bearbeitet", + "Emoji": "Emoji", + "HoursAgo": "{hours, plural, =0 {vor weniger als einer Stunde} =1 {vor einer Stunde} other {vor # Stunden}}", + "JustNow": "Gerade eben", + "LastReply": "Letzte Antwort", + "Mention": "Erwähnen", + "MinutesAgo": "{minutes, plural, =0 {vor weniger als einer Minute} =1 {vor einer Minute} other {vor # Minuten}}", + "MonthAt": "{month} um {time}", + "New": "Neu", + "Removed": "Entfernt", + "RepliesCount": "{count} Antworten", + "Reply": "Antworten", + "Send": "Senden", + "Set": "Festlegen", + "ShowFormatting": "Formatierung anzeigen", + "To": "An", + "Today": "Heute", + "Unset": "Nicht festgelegt", + "WeekdayAt": "{weekday} um {time}", + "YearAt": "{year} um {time}", + "Yesterday": "Gestern", + "YesterdayAt": "Gestern um {time}" + } +} diff --git a/packages/ui-next/lang/en.json b/packages/ui-next/lang/en.json new file mode 100644 index 00000000000..ada9377dbdb --- /dev/null +++ b/packages/ui-next/lang/en.json @@ -0,0 +1,30 @@ +{ + "string": { + "Added": "Added", + "Attach": "Attach", + "Cancel": "Cancel", + "Edit": "Edit", + "Edited": "Edited", + "Emoji": "Emoji", + "HoursAgo": "{hours, plural, =0 {less than an hour ago} =1 {an hour ago} other {# hours ago}}", + "JustNow": "Just now", + "LastReply": "Last reply", + "Mention": "Mention", + "MinutesAgo": "{minutes, plural, =0 {less than a minute ago} =1 {a minute ago} other {# minutes ago}}", + "MonthAt": "{month} at {time}", + "New": "New", + "Removed": "Removed", + "RepliesCount": "{count} replies", + "Reply": "Reply", + "Send": "Send", + "Set": "Set", + "ShowFormatting": "Show formatting", + "To": "To", + "Today": "Today", + "Unset": "Unset", + "WeekdayAt": "{weekday} at {time}", + "YearAt": "{year} at {time}", + "Yesterday": "Yesterday", + "YesterdayAt": "Yesterday at {time}" + } +} diff --git a/packages/ui-next/lang/es.json b/packages/ui-next/lang/es.json new file mode 100644 index 00000000000..154602a5e95 --- /dev/null +++ b/packages/ui-next/lang/es.json @@ -0,0 +1,30 @@ +{ + "string": { + "Added": "Añadido", + "Attach": "Adjuntar", + "Cancel": "Cancelar", + "Edit": "Editar", + "Edited": "Editado", + "Emoji": "Emoji", + "HoursAgo": "{hours, plural, =0 {hace menos de una hora} =1 {hace una hora} other {hace # horas}}", + "JustNow": "Justo ahora", + "LastReply": "Última respuesta", + "Mention": "Mencionar", + "MinutesAgo": "{minutes, plural, =0 {hace menos de un minuto} =1 {hace un minuto} other {hace # minutos}}", + "MonthAt": "{month} a las {time}", + "New": "Nuevo", + "Removed": "Eliminado", + "RepliesCount": "{count} respuestas", + "Reply": "Responder", + "Send": "Enviar", + "Set": "Establecer", + "ShowFormatting": "Mostrar formato", + "To": "A", + "Today": "Hoy", + "Unset": "No establecido", + "WeekdayAt": "{weekday} a las {time}", + "YearAt": "{year} a las {time}", + "Yesterday": "Ayer", + "YesterdayAt": "Ayer a las {time}" + } +} diff --git a/packages/ui-next/lang/fr.json b/packages/ui-next/lang/fr.json new file mode 100644 index 00000000000..05a86af8856 --- /dev/null +++ b/packages/ui-next/lang/fr.json @@ -0,0 +1,30 @@ +{ + "string": { + "Added": "Ajouté", + "Attach": "Joindre", + "Cancel": "Annuler", + "Edit": "Modifier", + "Edited": "Modifié", + "Emoji": "Emoji", + "HoursAgo": "{hours, plural, =0 {il y a moins d'une heure} =1 {il y a une heure} other {il y a # heures}}", + "JustNow": "À l'instant", + "LastReply": "Dernière réponse", + "Mention": "Mentionner", + "MinutesAgo": "{minutes, plural, =0 {il y a moins d'une minute} =1 {il y a une minute} other {il y a # minutes}}", + "MonthAt": "{month} à {time}", + "New": "Nouveau", + "Removed": "Supprimé", + "RepliesCount": "{count} réponses", + "Reply": "Répondre", + "Send": "Envoyer", + "Set": "Définir", + "ShowFormatting": "Afficher la mise en forme", + "To": "À", + "Today": "Aujourd'hui", + "Unset": "Non défini", + "WeekdayAt": "{weekday} à {time}", + "YearAt": "{year} à {time}", + "Yesterday": "Hier", + "YesterdayAt": "Hier à {time}" + } +} diff --git a/packages/ui-next/lang/it.json b/packages/ui-next/lang/it.json new file mode 100644 index 00000000000..d544e1261c7 --- /dev/null +++ b/packages/ui-next/lang/it.json @@ -0,0 +1,30 @@ +{ + "string": { + "Added": "Aggiunto" , + "Attach": "Allega", + "Cancel": "Annulla", + "Edit": "Modifica", + "Edited": "Modificato", + "Emoji": "Emoji", + "HoursAgo": "{hours, plural, =0 {meno di un'ora fa} =1 {un'ora fa} other {# ore fa}}", + "JustNow": "Proprio adesso", + "LastReply": "Ultima risposta", + "Mention": "Menziona", + "MinutesAgo": "{minutes, plural, =0 {meno di un minuto fa} =1 {un minuto fa} other {# minuti fa}}", + "MonthAt": "{month} alle {time}", + "New": "Nuovo", + "Removed": "Rimosso", + "RepliesCount": "{count} risposte", + "Reply": "Rispondi", + "Send": "Invia", + "Set": "Imposta", + "ShowFormatting": "Mostra la formattazione", + "To": "A", + "Today": "Oggi", + "Unset": "Non impostato", + "WeekdayAt": "{weekday} alle {time}", + "YearAt": "{year} alle {time}", + "Yesterday": "Ieri", + "YesterdayAt": "Ieri alle {time}" + } +} diff --git a/packages/ui-next/lang/pt.json b/packages/ui-next/lang/pt.json new file mode 100644 index 00000000000..8990eadd4de --- /dev/null +++ b/packages/ui-next/lang/pt.json @@ -0,0 +1,30 @@ +{ + "string": { + "Added": "Adicionado", + "Attach": "Anexar", + "Cancel": "Cancelar", + "Edit": "Editar", + "Edited": "Editado", + "Emoji": "Emoji", + "HoursAgo": "{hours, plural, =0 {há menos de uma hora} =1 {há uma hora} other {há # horas}}", + "JustNow": "Agora mesmo", + "LastReply": "Última resposta", + "Mention": "Mencionar", + "MinutesAgo": "{minutes, plural, =0 {há menos de um minuto} =1 {há um minuto} other {há # minutos}}", + "MonthAt": "{month} às {time}", + "New": "Novo", + "Removed": "Removido", + "RepliesCount": "{count} respostas", + "Reply": "Responder", + "Send": "Enviar", + "Set": "Definir", + "ShowFormatting": "Mostrar formatação", + "To": "Para", + "Today": "Hoje", + "Unset": "Não definido", + "WeekdayAt": "{weekday} às {time}", + "YearAt": "{year} às {time}", + "Yesterday": "Ontem", + "YesterdayAt": "Ontem às {time}" + } +} diff --git a/packages/ui-next/lang/ru.json b/packages/ui-next/lang/ru.json new file mode 100644 index 00000000000..09e63991a9d --- /dev/null +++ b/packages/ui-next/lang/ru.json @@ -0,0 +1,29 @@ +{ + "string": { + "Added": "Добавлено", + "Attach": "Прикрепить", + "Cancel": "Отмена", + "Edit": "Редактировать", + "Edited": "Отредактировано", + "Emoji": "Эмодзи", + "HoursAgo": "{hours, plural, =0 {менее часа назад} =1 {час назад} other {# часов назад}}", + "JustNow": "Только что", + "LastReply": "Последний ответ", + "Mention": "Упомянуть", + "MinutesAgo": "{minutes, plural, =0 {менее минуты назад} =1 {минуту назад} other {# минут назад}}", + "MonthAt": "{month} в {time}", + "New": "Новый", + "Removed": "Удалено", + "RepliesCount": "{count} ответов", + "Reply": "Ответить", + "Send": "Отправить", + "Set": "Установлено", + "ShowFormatting": "Показать форматирование", + "To": "В", + "Today": "Сегодня", + "WeekdayAt": "{weekday} в {time}", + "YearAt": "{year} в {time}", + "Yesterday": "Вчера", + "YesterdayAt": "Вчера в {time}" + } +} diff --git a/packages/ui-next/lang/zh.json b/packages/ui-next/lang/zh.json new file mode 100644 index 00000000000..b54eafefa1c --- /dev/null +++ b/packages/ui-next/lang/zh.json @@ -0,0 +1,30 @@ +{ + "string": { + "Added": "已添加", + "Attach": "附加", + "Cancel": "取消", + "Edit": "编辑", + "Edited": "已编辑", + "Emoji": "表情", + "HoursAgo": "{hours, plural, =0 {不到一小时前} =1 {一小时前} other {#小时前}}", + "JustNow": "刚刚", + "LastReply": "最后回复", + "Mention": "提及", + "MinutesAgo": "{minutes, plural, =0 {不到一分钟前} =1 {一分钟前} other {#分钟前}}", + "MonthAt": "{month} 于 {time}", + "New": "新", + "Removed": "已删除", + "RepliesCount": "{count} 条回复", + "Reply": "回复", + "Send": "发送", + "Set": "设置", + "ShowFormatting": "显示格式", + "To": "到", + "Today": "今天", + "Unset": "未设置", + "WeekdayAt": "{weekday} 于 {time}", + "YearAt": "{year} 于 {time}", + "Yesterday": "昨天", + "YesterdayAt": "昨天 于 {time}" + } +} \ No newline at end of file diff --git a/packages/ui-next/package.json b/packages/ui-next/package.json new file mode 100644 index 00000000000..ddcc259195b --- /dev/null +++ b/packages/ui-next/package.json @@ -0,0 +1,68 @@ +{ + "name": "@hcengineering/ui-next", + "version": "0.6.0", + "main": "src/index.ts", + "author": "Copyright © Hardcore Engineering Inc.", + "license": "EPL-2.0", + "scripts": { + "build": "compile ui", + "build:watch": "compile ui", + "build:docs": "api-extractor run --local", + "format": "format src", + "svelte-check": "do-svelte-check", + "_phase:svelte-check": "do-svelte-check", + "_phase:build": "compile ui", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@types/dompurify": "^3.0.5", + "@types/jest": "^29.5.5", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint": "^8.54.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.4.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-svelte": "^2.35.1", + "jest": "^29.7.0", + "prettier": "^3.1.0", + "prettier-plugin-svelte": "^3.2.2", + "sass": "^1.53.0", + "svelte-check": "^3.6.9", + "svelte-eslint-parser": "^0.33.1", + "svelte-loader": "^3.2.0", + "svelte-preprocess": "^5.1.3", + "ts-jest": "^29.1.1", + "typescript": "^5.3.3" + }, + "dependencies": { + "@hcengineering/analytics": "^0.6.0", + "@hcengineering/attachment-resources": "^0.6.0", + "@hcengineering/card": "^0.6.0", + "@hcengineering/communication-types": "0.1.147", + "@hcengineering/contact": "^0.6.24", + "@hcengineering/contact-resources": "^0.6.0", + "@hcengineering/core": "^0.6.32", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/presentation": "^0.6.3", + "@hcengineering/text": "^0.6.5", + "@hcengineering/text-editor": "^0.6.0", + "@hcengineering/text-editor-resources": "^0.6.0", + "@hcengineering/text-markdown": "^0.6.0", + "@hcengineering/theme": "^0.6.5", + "@hcengineering/ui": "^0.6.15", + "@hcengineering/view": "^0.6.13", + "@hcengineering/view-resources": "^0.6.0", + "@tiptap/core": "^2.11.3", + "@tiptap/pm": "^2.11.3", + "fast-equals": "^5.2.2", + "svelte": "^4.2.19" + }, + "repository": "https://github.com/hcengineering/platform", + "publishConfig": { + "registry": "https://npm.pkg.github.com" + } +} diff --git a/packages/ui-next/postcss.config.js b/packages/ui-next/postcss.config.js new file mode 100644 index 00000000000..88752c6cb06 --- /dev/null +++ b/packages/ui-next/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: [ + require('autoprefixer') + ] +} diff --git a/packages/ui-next/src/activity.ts b/packages/ui-next/src/activity.ts new file mode 100644 index 00000000000..c78cbd208f1 --- /dev/null +++ b/packages/ui-next/src/activity.ts @@ -0,0 +1,109 @@ +// +// Copyright © 2025 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. +// +import core, { type Class, type Client, type Doc, type Mixin, type Ref } from '@hcengineering/core' +import view, { type AttributeModel } from '@hcengineering/view' +import { buildRemovedDoc, getAttributePresenter } from '@hcengineering/view-resources' +import { type Card } from '@hcengineering/card' +import { + type ActivityMessage, + type ActivityUpdate, + ActivityUpdateType, + type Message, + MessageType +} from '@hcengineering/communication-types' + +const valueTypes: ReadonlyArray>> = [ + core.class.TypeString, + core.class.EnumOf, + core.class.TypeNumber, + core.class.TypeDate, + core.class.TypeFileSize, + core.class.TypeMarkup, + core.class.TypeHyperlink +] + +async function getAttributePresenterSafe ( + client: Client, + _class: Ref>, + attrKey: string, + mixin?: Ref> +): Promise { + try { + return await getAttributePresenter(client, _class, attrKey, { key: attrKey }, mixin) + } catch (e) { + console.error(e) + } +} + +export async function getAttributeModel ( + client: Client, + update: ActivityUpdate | undefined, + _class: Ref> +): Promise { + if (update == null || update.type !== ActivityUpdateType.Attribute) return undefined + + const { attrKey } = update + + const model = await getAttributePresenterSafe( + client, + update.mixin ?? _class, + attrKey, + view.mixin.ActivityAttributePresenter + ) + + if (model !== undefined) { + return model + } + + return await getAttributePresenterSafe(client, update.mixin ?? _class, attrKey) +} + +export function isMarkupAttribute (model: AttributeModel): boolean { + return ( + model.attribute?.type?._class === core.class.TypeMarkup || + model.attribute?.type?._class === core.class.TypeCollaborativeDoc + ) +} + +export async function getAttributeValues ( + client: Client, + value: any | any[], + attrClass: Ref> +): Promise { + const values = Array.isArray(value) ? value : [value] + if (values.some((value) => typeof value !== 'string')) { + return values + } + + if (valueTypes.includes(attrClass)) { + return values + } + + const docs = await client.findAll(attrClass, { _id: { $in: values } }) + const docIds = docs.map(({ _id }) => _id) + const missedIds = values.filter((value) => !docIds.includes(value)) + const removedDocs = await Promise.all(missedIds.map(async (value) => await buildRemovedDoc(client, value, attrClass))) + const allDocs = [...docs, ...removedDocs].filter((doc) => !(doc == null)) + + if (allDocs.length > 0) { + return allDocs + } + + return values +} + +export function isActivityMessage (message: Message): message is ActivityMessage { + return message.type === MessageType.Activity +} diff --git a/packages/ui-next/src/components/Avatar.svelte b/packages/ui-next/src/components/Avatar.svelte new file mode 100644 index 00000000000..27667911b06 --- /dev/null +++ b/packages/ui-next/src/components/Avatar.svelte @@ -0,0 +1,136 @@ + + + + +
+ {#if url} + avatar + {:else} +
+ {/if} +
+ + diff --git a/packages/ui-next/src/components/Button.svelte b/packages/ui-next/src/components/Button.svelte new file mode 100644 index 00000000000..c7f23801400 --- /dev/null +++ b/packages/ui-next/src/components/Button.svelte @@ -0,0 +1,120 @@ + + + + + + + + diff --git a/packages/ui-next/src/components/DateSeparator.svelte b/packages/ui-next/src/components/DateSeparator.svelte new file mode 100644 index 00000000000..9aa4da833db --- /dev/null +++ b/packages/ui-next/src/components/DateSeparator.svelte @@ -0,0 +1,77 @@ + + + + +
+
+ {#await formatDate(date, $themeStore.language) then date} + {date} + {/await} +
+
+ + diff --git a/packages/ui-next/src/components/Divider.svelte b/packages/ui-next/src/components/Divider.svelte new file mode 100644 index 00000000000..0578916b916 --- /dev/null +++ b/packages/ui-next/src/components/Divider.svelte @@ -0,0 +1,23 @@ + +
+ + diff --git a/packages/ui-next/src/components/Icon.svelte b/packages/ui-next/src/components/Icon.svelte new file mode 100644 index 00000000000..a13920e4f76 --- /dev/null +++ b/packages/ui-next/src/components/Icon.svelte @@ -0,0 +1,41 @@ + + + + +{#if isAsset(icon) && url} + + + +{:else if typeof icon !== 'string'} + +{/if} diff --git a/packages/ui-next/src/components/Label.svelte b/packages/ui-next/src/components/Label.svelte new file mode 100644 index 00000000000..e23b250fcb3 --- /dev/null +++ b/packages/ui-next/src/components/Label.svelte @@ -0,0 +1,39 @@ + + + + +{#if _value !== undefined} + {_value} +{:else} + {label} +{/if} diff --git a/packages/ui-next/src/components/Menu.svelte b/packages/ui-next/src/components/Menu.svelte new file mode 100644 index 00000000000..e9ac9fda011 --- /dev/null +++ b/packages/ui-next/src/components/Menu.svelte @@ -0,0 +1,8 @@ + + + + diff --git a/packages/ui-next/src/components/NavItem.svelte b/packages/ui-next/src/components/NavItem.svelte new file mode 100644 index 00000000000..b5446c72e05 --- /dev/null +++ b/packages/ui-next/src/components/NavItem.svelte @@ -0,0 +1,109 @@ + + + + + + + diff --git a/packages/ui-next/src/components/NavigationList.svelte b/packages/ui-next/src/components/NavigationList.svelte new file mode 100644 index 00000000000..2b299b250a9 --- /dev/null +++ b/packages/ui-next/src/components/NavigationList.svelte @@ -0,0 +1,54 @@ + + + + + + + diff --git a/packages/ui-next/src/components/ReactionPresenter.svelte b/packages/ui-next/src/components/ReactionPresenter.svelte new file mode 100644 index 00000000000..70ba3695019 --- /dev/null +++ b/packages/ui-next/src/components/ReactionPresenter.svelte @@ -0,0 +1,81 @@ + + + + + + + + +
+
+ {#if icon} + + {:else} + {emoji} + {/if} +
+ {#if count !== undefined} +
{count}
+ {/if} +
+ + diff --git a/packages/ui-next/src/components/ReactionsList.svelte b/packages/ui-next/src/components/ReactionsList.svelte new file mode 100644 index 00000000000..ecc22d4852c --- /dev/null +++ b/packages/ui-next/src/components/ReactionsList.svelte @@ -0,0 +1,76 @@ + + + + +
+ {#each reactionsByEmoji as [emoji, reactions] (emoji)} + me.socialIds.includes(it.creator))} + count={reactions.length} + on:click={() => dispatch('click', emoji)} + /> + {/each} + +
+ + diff --git a/packages/ui-next/src/components/Section.svelte b/packages/ui-next/src/components/Section.svelte new file mode 100644 index 00000000000..87965370a7b --- /dev/null +++ b/packages/ui-next/src/components/Section.svelte @@ -0,0 +1,102 @@ + + + + +
+ + +
+
+
+
+ {#if _expanded} + + {:else} + + {/if} +
+ {#if withHeaderDivider} + + {/if} +
+ +
+ {#if _expanded} + + {/if} +
+
+ + diff --git a/packages/ui-next/src/components/TextInput.svelte b/packages/ui-next/src/components/TextInput.svelte new file mode 100644 index 00000000000..bdf06de8af6 --- /dev/null +++ b/packages/ui-next/src/components/TextInput.svelte @@ -0,0 +1,248 @@ + + + +
+ {#if $$slots.header} + + {/if} +
+ { + if (canSubmit(loading, content, hasNonTextContent)) { + dispatch('submit', ev.detail) + content = EmptyMarkup + editor?.clear?.() + } + }} + on:blur={() => { + focused = false + dispatch('blur') + }} + on:focus={() => { + focused = true + updateFocus() + dispatch('focus') + }} + extensions={[ + completionPlugin, + EmojiExtension.configure(), + IsEmptyContentExtension.configure({ onChange: (value) => (isEmpty = value) }) + ]} + on:update + /> +
+ +
+ + diff --git a/packages/ui-next/src/components/icons/IconArrowChevronDown.svelte b/packages/ui-next/src/components/icons/IconArrowChevronDown.svelte new file mode 100644 index 00000000000..96f3ff5e352 --- /dev/null +++ b/packages/ui-next/src/components/icons/IconArrowChevronDown.svelte @@ -0,0 +1,26 @@ + + + + + + + diff --git a/packages/ui-next/src/components/icons/IconArrowChevronRight.svelte b/packages/ui-next/src/components/icons/IconArrowChevronRight.svelte new file mode 100644 index 00000000000..d9777328673 --- /dev/null +++ b/packages/ui-next/src/components/icons/IconArrowChevronRight.svelte @@ -0,0 +1,26 @@ + + + + + + + diff --git a/packages/ui-next/src/components/icons/IconAt.svelte b/packages/ui-next/src/components/icons/IconAt.svelte new file mode 100644 index 00000000000..9e975090b6a --- /dev/null +++ b/packages/ui-next/src/components/icons/IconAt.svelte @@ -0,0 +1,28 @@ + + + + + + + diff --git a/packages/ui-next/src/components/icons/IconEmoji.svelte b/packages/ui-next/src/components/icons/IconEmoji.svelte new file mode 100644 index 00000000000..d394159314c --- /dev/null +++ b/packages/ui-next/src/components/icons/IconEmoji.svelte @@ -0,0 +1,38 @@ + + + + + + + + + diff --git a/packages/ui-next/src/components/icons/IconEmojiAdd.svelte b/packages/ui-next/src/components/icons/IconEmojiAdd.svelte new file mode 100644 index 00000000000..02da3cb0177 --- /dev/null +++ b/packages/ui-next/src/components/icons/IconEmojiAdd.svelte @@ -0,0 +1,38 @@ + + + + + + + + + + + diff --git a/packages/ui-next/src/components/icons/IconPen.svelte b/packages/ui-next/src/components/icons/IconPen.svelte new file mode 100644 index 00000000000..17bb2e19a88 --- /dev/null +++ b/packages/ui-next/src/components/icons/IconPen.svelte @@ -0,0 +1,28 @@ + + + + + + + diff --git a/packages/ui-next/src/components/icons/IconPlus.svelte b/packages/ui-next/src/components/icons/IconPlus.svelte new file mode 100644 index 00000000000..7401a52840b --- /dev/null +++ b/packages/ui-next/src/components/icons/IconPlus.svelte @@ -0,0 +1,26 @@ + + + + + + + diff --git a/packages/ui-next/src/components/icons/IconSend.svelte b/packages/ui-next/src/components/icons/IconSend.svelte new file mode 100644 index 00000000000..3411ccff4f6 --- /dev/null +++ b/packages/ui-next/src/components/icons/IconSend.svelte @@ -0,0 +1,28 @@ + + + + + + + diff --git a/packages/ui-next/src/components/icons/IconTextFont.svelte b/packages/ui-next/src/components/icons/IconTextFont.svelte new file mode 100644 index 00000000000..919d678880e --- /dev/null +++ b/packages/ui-next/src/components/icons/IconTextFont.svelte @@ -0,0 +1,29 @@ + + + + + + + + diff --git a/packages/ui-next/src/components/message/ActivityMessageViewer.svelte b/packages/ui-next/src/components/message/ActivityMessageViewer.svelte new file mode 100644 index 00000000000..760a63f09e8 --- /dev/null +++ b/packages/ui-next/src/components/message/ActivityMessageViewer.svelte @@ -0,0 +1,45 @@ + + + + +{#if data.action === 'create'} + +{:else if data.update && data.action === 'update'} + +{/if} diff --git a/packages/ui-next/src/components/message/MessageContentViewer.svelte b/packages/ui-next/src/components/message/MessageContentViewer.svelte new file mode 100644 index 00000000000..a3f7688103a --- /dev/null +++ b/packages/ui-next/src/components/message/MessageContentViewer.svelte @@ -0,0 +1,33 @@ + + + + +{#if message.type === MessageType.Message} + +{:else if isActivityMessage(message)} + +{/if} diff --git a/packages/ui-next/src/components/message/MessageInput.svelte b/packages/ui-next/src/components/message/MessageInput.svelte new file mode 100644 index 00000000000..af67bcaa31f --- /dev/null +++ b/packages/ui-next/src/components/message/MessageInput.svelte @@ -0,0 +1,203 @@ + + + + + + 0} + actions={[...defaultMessageInputActions, attachAction]} + on:submit={handleSubmit} + onCancel={onCancel ? handleCancel : undefined} +> +
+ {#if files.length > 0} +
+ {#each files as file (file.blobId)} +
+ { + if (result !== undefined) { + files = files.filter((it) => it.blobId !== file.blobId) + void deleteFile(file.blobId) + } + }} + /> +
+ {/each} +
+ {/if} +
+
+ + diff --git a/packages/ui-next/src/components/message/MessagePresenter.svelte b/packages/ui-next/src/components/message/MessagePresenter.svelte new file mode 100644 index 00000000000..52a5fb1024b --- /dev/null +++ b/packages/ui-next/src/components/message/MessagePresenter.svelte @@ -0,0 +1,281 @@ + + + + + + +
+
+ +
+ +
+
+
+
+ {formatName(author?.name ?? '')} +
+
+ {formatDate(message.created)} +
+ {#if message.edited} +
+
+ {/if} +
+ {#if !isEditing} +
+ +
+ {:else} + + {/if} +
+
+ {#if message.files.length > 0} +
+ {#each message.files as file (file.blobId)} + + {/each} +
+ {/if} + {#if message.reactions.length > 0} +
+ +
+ {/if} + {#if message.thread && message.thread.repliesCount > 0} +
+ dispatch('reply', message)} + /> +
+ {/if} +
+ + diff --git a/packages/ui-next/src/components/message/MessageReplies.svelte b/packages/ui-next/src/components/message/MessageReplies.svelte new file mode 100644 index 00000000000..1246206b7f2 --- /dev/null +++ b/packages/ui-next/src/components/message/MessageReplies.svelte @@ -0,0 +1,164 @@ + + + + + + +
+
+
+ +
+
+
+ + diff --git a/packages/ui-next/src/components/message/MessagesGroup.svelte b/packages/ui-next/src/components/message/MessagesGroup.svelte new file mode 100644 index 00000000000..9426a99e08a --- /dev/null +++ b/packages/ui-next/src/components/message/MessagesGroup.svelte @@ -0,0 +1,75 @@ + + + + +
+ {#if showDates} + + {/if} +
+ {#each messages as message, index (message.id)} + {#if index === separatorIndex} + + {/if} + + {/each} +
+
+ + diff --git a/packages/ui-next/src/components/message/MessagesSeparator.svelte b/packages/ui-next/src/components/message/MessagesSeparator.svelte new file mode 100644 index 00000000000..a22d6a30cb2 --- /dev/null +++ b/packages/ui-next/src/components/message/MessagesSeparator.svelte @@ -0,0 +1,30 @@ + + + +
+
+
+ + diff --git a/packages/ui-next/src/components/message/activity/ActivityAttributeValue.svelte b/packages/ui-next/src/components/message/activity/ActivityAttributeValue.svelte new file mode 100644 index 00000000000..c4d3d1e8270 --- /dev/null +++ b/packages/ui-next/src/components/message/activity/ActivityAttributeValue.svelte @@ -0,0 +1,63 @@ + + + + + + + + + + + {#each attributeValues as value} + + {#if value != null && typeof value === 'object'} + + {:else} + + {/if} + + {/each} + + + diff --git a/packages/ui-next/src/components/message/activity/ActivityObjectValue.svelte b/packages/ui-next/src/components/message/activity/ActivityObjectValue.svelte new file mode 100644 index 00000000000..3e258c45fae --- /dev/null +++ b/packages/ui-next/src/components/message/activity/ActivityObjectValue.svelte @@ -0,0 +1,68 @@ + + + + + {#if clazz.icon} + + + + {/if} + + {#if action === 'create'} + + + diff --git a/packages/ui-next/src/components/message/activity/ActivitySetAttributeViewer.svelte b/packages/ui-next/src/components/message/activity/ActivitySetAttributeViewer.svelte new file mode 100644 index 00000000000..0a744477dd5 --- /dev/null +++ b/packages/ui-next/src/components/message/activity/ActivitySetAttributeViewer.svelte @@ -0,0 +1,55 @@ + + + +{#if isUnset} + + + +{:else if isMarkupAttribute(model)} + +{:else} + + + + +{/if} diff --git a/packages/ui-next/src/components/message/activity/ActivityUpdateAttributeViewer.svelte b/packages/ui-next/src/components/message/activity/ActivityUpdateAttributeViewer.svelte new file mode 100644 index 00000000000..b6d42b3e90b --- /dev/null +++ b/packages/ui-next/src/components/message/activity/ActivityUpdateAttributeViewer.svelte @@ -0,0 +1,27 @@ + + + +{#if update?.set !== undefined} + +{/if} diff --git a/packages/ui-next/src/components/message/activity/ActivityUpdateTagViewer.svelte b/packages/ui-next/src/components/message/activity/ActivityUpdateTagViewer.svelte new file mode 100644 index 00000000000..893c947477f --- /dev/null +++ b/packages/ui-next/src/components/message/activity/ActivityUpdateTagViewer.svelte @@ -0,0 +1,67 @@ + + + +{#if update.action === 'add'} +
+ +
+{:else if update.action === 'remove'} +
+ +
+{/if} + + diff --git a/packages/ui-next/src/components/message/activity/ActivityUpdateViewer.svelte b/packages/ui-next/src/components/message/activity/ActivityUpdateViewer.svelte new file mode 100644 index 00000000000..cc076beca31 --- /dev/null +++ b/packages/ui-next/src/components/message/activity/ActivityUpdateViewer.svelte @@ -0,0 +1,30 @@ + + + +{#if update.type === ActivityUpdateType.Attribute && model} + +{:else if update.type === ActivityUpdateType.Tag} + +{/if} diff --git a/packages/ui-next/src/index.ts b/packages/ui-next/src/index.ts new file mode 100644 index 00000000000..8e385de9d94 --- /dev/null +++ b/packages/ui-next/src/index.ts @@ -0,0 +1,33 @@ +// +// Copyright © 2025 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. +// + +import uiNext, { uiNextId } from './plugin' +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { type SvelteComponent } from 'svelte' + +export * from './types' +export { uiNextId } +export default uiNext + +export { default as Avatar } from './components/Avatar.svelte' +export { default as Icon } from './components/Icon.svelte' +export { default as Label } from './components/Label.svelte' +export { default as MessagePresenter } from './components/message/MessagePresenter.svelte' +export { default as MessageInput } from './components/message/MessageInput.svelte' +export { default as MessagesGroup } from './components/message/MessagesGroup.svelte' +export { default as NavItem } from './components/NavItem.svelte' +export { default as NavigationList } from './components/NavigationList.svelte' +export { default as Section } from './components/Section.svelte' +export { default as Divider } from './components/Divider.svelte' diff --git a/packages/ui-next/src/plugin.ts b/packages/ui-next/src/plugin.ts new file mode 100644 index 00000000000..18aafb8f811 --- /dev/null +++ b/packages/ui-next/src/plugin.ts @@ -0,0 +1,53 @@ +// +// Copyright © 2025 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. +// + +import { addLocation, type IntlString, type Plugin, plugin } from '@hcengineering/platform' + +export const uiNextId = 'ui-next' as Plugin + +export const uiNext = plugin(uiNextId, { + string: { + Added: '' as IntlString, + Attach: '' as IntlString, + Cancel: '' as IntlString, + Edit: '' as IntlString, + Edited: '' as IntlString, + Emoji: '' as IntlString, + HoursAgo: '' as IntlString, + JustNow: '' as IntlString, + LastReply: '' as IntlString, + Mention: '' as IntlString, + MinutesAgo: '' as IntlString, + MonthAt: '' as IntlString, + New: '' as IntlString, + Removed: '' as IntlString, + RepliesCount: '' as IntlString, + Reply: '' as IntlString, + Send: '' as IntlString, + Set: '' as IntlString, + ShowFormatting: '' as IntlString, + To: '' as IntlString, + Today: '' as IntlString, + Unset: '' as IntlString, + WeekdayAt: '' as IntlString, + YearAt: '' as IntlString, + Yesterday: '' as IntlString, + YesterdayAt: '' as IntlString + } +}) + +addLocation(uiNextId, async () => ({ default: async () => ({}) })) + +export default uiNext diff --git a/packages/ui-next/src/types.ts b/packages/ui-next/src/types.ts new file mode 100644 index 00000000000..1cd0bbf66ac --- /dev/null +++ b/packages/ui-next/src/types.ts @@ -0,0 +1,86 @@ +// +// Copyright © 2025 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. +// + +import { type Asset, type IntlString } from '@hcengineering/platform' +import { type ComponentType } from 'svelte' +import { type TextEditorHandler } from '@hcengineering/text-editor' +import { type BlobID } from '@hcengineering/communication-types' + +export interface NavigationSection { + id: string + title: IntlString + expanded: boolean + items: NavigationSectionItem[] +} + +export interface NavigationSectionItem { + id: string + label: string + icon: IconComponent + notificationsCount?: number +} + +export type IconSize = 'x-small' | 'small' | 'medium' | 'large' +export type IconComponent = Asset | ComponentType + +export enum AvatarSize { + XSmall = 'x-small', + Small = 'small', + Regular = 'regular', + Medium = 'medium', + Large = 'large', + XLarge = 'x-large', + XXLarge = 'xx-large', + XXXLarge = 'xxx-large' +} + +export enum AvatarShape { + Circle = 'circle' +} + +export enum ButtonVariant { + Default = 'default', + Ghost = 'ghost' +} + +export enum ButtonType { + Submit = 'submit', + Reset = 'reset', + Button = 'button' +} + +export enum ButtonSize { + Auto = 'auto', + Small = 'small', + Medium = 'medium', + Large = 'large' +} + +export type TextInputActionFn = (element: HTMLElement, editor: TextEditorHandler, event?: MouseEvent) => void + +export interface TextInputAction { + label: IntlString + icon: IconComponent + action: TextInputActionFn + order: number + disabled?: boolean +} + +export interface UploadedFile { + blobId: BlobID + type: string + filename: string + size: number +} diff --git a/packages/ui-next/src/utils.ts b/packages/ui-next/src/utils.ts new file mode 100644 index 00000000000..28f8ef5ee70 --- /dev/null +++ b/packages/ui-next/src/utils.ts @@ -0,0 +1,87 @@ +// +// Copyright © 2025 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. +// +import { EmojiPopup, showPopup } from '@hcengineering/ui' +import { getCurrentAccount, type Markup } from '@hcengineering/core' +import { markupToJSON, jsonToMarkup } from '@hcengineering/text' +import { markupToMarkdown, markdownToMarkup } from '@hcengineering/text-markdown' +import { type Message } from '@hcengineering/communication-types' +import { getCommunicationClient } from '@hcengineering/presentation' + +import IconAt from './components/icons/IconAt.svelte' +import IconEmoji from './components/icons/IconEmoji.svelte' +import IconTextFont from './components/icons/IconTextFont.svelte' +import { type TextInputAction } from './types' +import uiNext from './plugin' + +export const defaultMessageInputActions: TextInputAction[] = [ + { + label: uiNext.string.ShowFormatting, + icon: IconTextFont, + action: (_element, editorHandler) => { + // TODO: implement + }, + order: 2000 + }, + { + label: uiNext.string.Emoji, + icon: IconEmoji, + action: (element, editorHandler) => { + showPopup( + EmojiPopup, + {}, + element, + (emoji) => { + if (emoji === null || emoji === undefined) { + return + } + + editorHandler.insertText(emoji) + editorHandler.focus() + }, + () => {} + ) + }, + order: 3000 + }, + { + label: uiNext.string.Mention, + icon: IconAt, + action: (_element, editorHandler) => { + editorHandler.insertText('@') + editorHandler.focus() + }, + order: 4000 + } +] + +export function toMarkdown (markup: Markup): string { + return markupToMarkdown(markupToJSON(markup)) +} + +export function toMarkup (markdown: string): Markup { + return jsonToMarkup(markdownToMarkup(markdown)) +} + +export async function toggleReaction (message: Message, emoji: string): Promise { + const me = getCurrentAccount() + const communicationClient = getCommunicationClient() + const { socialIds } = me + const reaction = message.reactions.find((it) => it.reaction === emoji && socialIds.includes(it.creator)) + if (reaction !== undefined) { + await communicationClient.removeReaction(message.card, message.id, emoji) + } else { + await communicationClient.createReaction(message.card, message.id, emoji) + } +} diff --git a/packages/ui-next/svelte.config.js b/packages/ui-next/svelte.config.js new file mode 100644 index 00000000000..944a06f73ee --- /dev/null +++ b/packages/ui-next/svelte.config.js @@ -0,0 +1,5 @@ +const sveltePreprocess = require('svelte-preprocess') + +module.exports = { + preprocess: sveltePreprocess() +}; \ No newline at end of file diff --git a/packages/ui-next/tsconfig.json b/packages/ui-next/tsconfig.json new file mode 100644 index 00000000000..fb6ccb2d182 --- /dev/null +++ b/packages/ui-next/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/ui/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types" + } +} \ No newline at end of file diff --git a/packages/ui/src/location.ts b/packages/ui/src/location.ts index 3633784509b..c86ef2d1941 100644 --- a/packages/ui/src/location.ts +++ b/packages/ui/src/location.ts @@ -244,7 +244,7 @@ export function restoreLocation (loc: PlatformLocation, app: Plugin): void { if (last !== null) { const newLocation: PlatformLocation = JSON.parse(last) - if (newLocation.path[3] != null) { + if (newLocation.path[1] === loc.path[1] && newLocation.path[3] != null) { loc.path[3] = newLocation.path[3] as Ref loc.path[4] = newLocation.path[4] if (loc.path[4] == null) { diff --git a/plugins/activity-assets/lang/cs.json b/plugins/activity-assets/lang/cs.json index 767f78b7dc1..80e6ef28029 100644 --- a/plugins/activity-assets/lang/cs.json +++ b/plugins/activity-assets/lang/cs.json @@ -50,6 +50,9 @@ "RemovedObject": "Odstraněný {object}", "ChangedObject": "Změněný {object}", "UnsetObject": "Zrušený {object}", - "UpdatedObject": "Aktualizovaný {object}" + "UpdatedObject": "Aktualizovaný {object}", + "NewObjectType": "Nový {type}: {title}", + "RemovedObjectType": "Odstraněný {type} : {title}", + "AttributeSetTo": "{name} nastaveno na {value}" } } \ No newline at end of file diff --git a/plugins/activity-assets/lang/de.json b/plugins/activity-assets/lang/de.json index c173e680e0e..5738bd1ac93 100644 --- a/plugins/activity-assets/lang/de.json +++ b/plugins/activity-assets/lang/de.json @@ -50,6 +50,9 @@ "RemovedObject": "{object} entfernt", "ChangedObject": "{object} geändert", "UnsetObject": "{object} zurückgesetzt", - "UpdatedObject": "{object} aktualisiert" + "UpdatedObject": "{object} aktualisiert", + "NewObjectType": "Neues {objectType}", + "RemovedObjectType": "{objectType} entfernt", + "AttributeSetTo": "{attribute} auf {value} gesetzt" } } \ No newline at end of file diff --git a/plugins/activity-assets/lang/en.json b/plugins/activity-assets/lang/en.json index c99cdfca977..b461271500b 100644 --- a/plugins/activity-assets/lang/en.json +++ b/plugins/activity-assets/lang/en.json @@ -50,6 +50,9 @@ "RemovedObject": "Removed {object}", "ChangedObject": "Changed {object}", "UnsetObject": "Unset {object}", - "UpdatedObject": "Updated {object}" + "UpdatedObject": "Updated {object}", + "NewObjectType": "New {type}: {title}", + "RemovedObjectType": "Removed {type} : {title}", + "AttributeSetTo": "{name} set to {value}" } } \ No newline at end of file diff --git a/plugins/activity-assets/lang/es.json b/plugins/activity-assets/lang/es.json index ac5045b2822..90858833c53 100644 --- a/plugins/activity-assets/lang/es.json +++ b/plugins/activity-assets/lang/es.json @@ -49,6 +49,9 @@ "RemovedObject": "Eliminado {object}", "ChangedObject": "Cambiado {object}", "UnsetObject": "No establecido {object}", - "UpdatedObject": "Actualizado {object}" + "UpdatedObject": "Actualizado {object}", + "NewObjectType": "Nuevo {type}: {title}", + "RemovedObjectType": "Eliminado {type} : {title}", + "AttributeSetTo": "{name} establecido en {value}" } } \ No newline at end of file diff --git a/plugins/activity-assets/lang/fr.json b/plugins/activity-assets/lang/fr.json index 713893222b2..c33b0089906 100644 --- a/plugins/activity-assets/lang/fr.json +++ b/plugins/activity-assets/lang/fr.json @@ -50,6 +50,9 @@ "RemovedObject": "Supprimé {object}", "ChangedObject": "Modifié {object}", "UnsetObject": "Non défini {object}", - "UpdatedObject": "Mis à jour {object}" + "UpdatedObject": "Mis à jour {object}", + "NewObjectType": "Nouveau {type}: {title}", + "RemovedObjectType": "Supprimé {type} : {title}", + "AttributeSetTo": "{name} défini sur {value}" } } \ No newline at end of file diff --git a/plugins/activity-assets/lang/it.json b/plugins/activity-assets/lang/it.json index 13afef9f616..20f470d8653 100644 --- a/plugins/activity-assets/lang/it.json +++ b/plugins/activity-assets/lang/it.json @@ -50,6 +50,9 @@ "RemovedObject": "{object} rimosso", "ChangedObject": "{object} modificato", "UnsetObject": "Annulla {object}", - "UpdatedObject": "{object} aggiornato" + "UpdatedObject": "{object} aggiornato", + "NewObjectType": "Nuovo {type}: {title}", + "RemovedObjectType": "{type} rimosso: {title}", + "AttributeSetTo": "{name} impostato su {value}" } } diff --git a/plugins/activity-assets/lang/pt.json b/plugins/activity-assets/lang/pt.json index ac14b0a0267..37e59ddc806 100644 --- a/plugins/activity-assets/lang/pt.json +++ b/plugins/activity-assets/lang/pt.json @@ -49,6 +49,9 @@ "RemovedObject": "Removido {object}", "ChangedObject": "Alterado {object}", "UnsetObject": "Não definido {object}", - "UpdatedObject": "Atualizado {object}" + "UpdatedObject": "Atualizado {object}", + "NewObjectType": "Novo {type}: {title}", + "RemovedObjectType": "Removido {type} : {title}", + "AttributeSetTo": "{name} definido para {value}" } } \ No newline at end of file diff --git a/plugins/activity-assets/lang/ru.json b/plugins/activity-assets/lang/ru.json index 02a85963839..e52eb90fb38 100644 --- a/plugins/activity-assets/lang/ru.json +++ b/plugins/activity-assets/lang/ru.json @@ -50,6 +50,9 @@ "RemovedObject": "Удален(ы) {object}", "ChangedObject": "Изменил(а) {object}", "UnsetObject": "Сбросил(а) {object}", - "UpdatedObject": "Обновил(а) {object}" + "UpdatedObject": "Обновил(а) {object}", + "NewObjectType": "Новый(ые) {type}: {title}", + "RemovedObjectType": "Удален(ы) {type} : {title}", + "AttributeSetTo": "{name} установлен на {value}" } } \ No newline at end of file diff --git a/plugins/activity-assets/lang/zh.json b/plugins/activity-assets/lang/zh.json index 206af5669c9..1e682c40e77 100644 --- a/plugins/activity-assets/lang/zh.json +++ b/plugins/activity-assets/lang/zh.json @@ -50,6 +50,9 @@ "RemovedObject": "移除 {object}", "ChangedObject": "更改 {object}", "UnsetObject": "取消设置 {object}", - "UpdatedObject": "更新 {object}" + "UpdatedObject": "更新 {object}", + "NewObjectType": "新 {type}: {title}", + "RemovedObjectType": "移除 {type} : {title}", + "AttributeSetTo": "{name} 设置为 {value}" } } diff --git a/plugins/activity-resources/package.json b/plugins/activity-resources/package.json index 1154dd4715a..97d07619e31 100644 --- a/plugins/activity-resources/package.json +++ b/plugins/activity-resources/package.json @@ -38,6 +38,7 @@ }, "dependencies": { "@hcengineering/activity": "^0.6.0", + "@hcengineering/card": "^0.6.0", "@hcengineering/contact": "^0.6.24", "@hcengineering/contact-resources": "^0.6.0", "@hcengineering/core": "^0.6.32", @@ -47,8 +48,10 @@ "@hcengineering/presentation": "^0.6.3", "@hcengineering/text": "^0.6.5", "@hcengineering/ui": "^0.6.15", + "@hcengineering/ui-next": "^0.6.0", "@hcengineering/view": "^0.6.13", "@hcengineering/view-resources": "^0.6.0", + "@hcengineering/communication-types": "0.1.147", "svelte": "^4.2.19" } } diff --git a/plugins/activity-resources/src/components/NewActivity.svelte b/plugins/activity-resources/src/components/NewActivity.svelte new file mode 100644 index 00000000000..024dd89b3b7 --- /dev/null +++ b/plugins/activity-resources/src/components/NewActivity.svelte @@ -0,0 +1,133 @@ + + + +
+
+ + {#if isLoading} +
+ +
+ {/if} +
+ + +
+ {#if messages.length} + + {#each messages as message (message.id)} + + {/each} + + {/if} +
+ {#if showInput} +
+ +
+ {/if} +
+
+
+ + diff --git a/plugins/activity-resources/src/index.ts b/plugins/activity-resources/src/index.ts index 3214143f1f0..bd239430c5e 100644 --- a/plugins/activity-resources/src/index.ts +++ b/plugins/activity-resources/src/index.ts @@ -16,6 +16,7 @@ import { type Resources } from '@hcengineering/platform' import Activity from './components/Activity.svelte' +import NewActivity from './components/NewActivity.svelte' import ActivityMessagePresenter from './components/activity-message/ActivityMessagePresenter.svelte' import DocUpdateMessagePresenter from './components/doc-update-message/DocUpdateMessagePresenter.svelte' import ActivityInfoMessagePresenter from './components/activity-info-message/ActivityInfoMessagePresenter.svelte' @@ -67,6 +68,7 @@ export { default as BasePreview } from './components/BasePreview.svelte' export default async (): Promise => ({ component: { Activity, + NewActivity, ActivityMessagePresenter, DocUpdateMessagePresenter, ReactionPresenter, diff --git a/plugins/activity/src/index.ts b/plugins/activity/src/index.ts index 9e602708cb7..450163312dc 100644 --- a/plugins/activity/src/index.ts +++ b/plugins/activity/src/index.ts @@ -317,10 +317,14 @@ export default plugin(activityId, { RemovedObject: '' as IntlString, ChangedObject: '' as IntlString, UnsetObject: '' as IntlString, - UpdatedObject: '' as IntlString + UpdatedObject: '' as IntlString, + NewObjectType: '' as IntlString, + RemovedObjectType: '' as IntlString, + AttributeSetTo: '' as IntlString }, component: { Activity: '' as AnyComponent, + NewActivity: '' as AnyComponent, ActivityMessagePresenter: '' as AnyComponent, DocUpdateMessagePresenter: '' as AnyComponent, ActivityInfoMessagePresenter: '' as AnyComponent, diff --git a/plugins/board-resources/src/components/LabelsView.svelte b/plugins/board-resources/src/components/LabelsView.svelte index 178f0ca138d..30ee8e69523 100644 --- a/plugins/board-resources/src/components/LabelsView.svelte +++ b/plugins/board-resources/src/components/LabelsView.svelte @@ -12,6 +12,6 @@ icon: tags.icon.Tags, item: board.string.Labels, key: 'labels', - сreateItemLabel: board.string.Labels + createItemLabel: board.string.Labels }} /> diff --git a/plugins/card-resources/src/components/EditCard.svelte b/plugins/card-resources/src/components/EditCard.svelte index 4b09c5f2797..dbe4d265d4e 100644 --- a/plugins/card-resources/src/components/EditCard.svelte +++ b/plugins/card-resources/src/components/EditCard.svelte @@ -143,6 +143,7 @@ bind:content bind:innerWidth floatAside={false} + newActivity on:open on:close={() => dispatch('close')} > diff --git a/plugins/chat-assets/.eslintrc.js b/plugins/chat-assets/.eslintrc.js new file mode 100644 index 00000000000..e73094bc7e5 --- /dev/null +++ b/plugins/chat-assets/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/assets/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/plugins/chat-assets/assets/icons.svg b/plugins/chat-assets/assets/icons.svg new file mode 100644 index 00000000000..8d4e25ae67e --- /dev/null +++ b/plugins/chat-assets/assets/icons.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/plugins/chat-assets/config/rig.json b/plugins/chat-assets/config/rig.json new file mode 100644 index 00000000000..b75800b9b70 --- /dev/null +++ b/plugins/chat-assets/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "assets" +} diff --git a/plugins/chat-assets/jest.config.js b/plugins/chat-assets/jest.config.js new file mode 100644 index 00000000000..2cfd408b679 --- /dev/null +++ b/plugins/chat-assets/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/plugins/chat-assets/lang/cs.json b/plugins/chat-assets/lang/cs.json new file mode 100644 index 00000000000..8e07ef891e3 --- /dev/null +++ b/plugins/chat-assets/lang/cs.json @@ -0,0 +1,13 @@ +{ + "string": { + "Channel": "Kanál", + "Channels": "Kanály", + "Chat": "Chat", + "Description": "Popis", + "Loading": "Načítání...", + "MessageIn": "Zpráva v #{title}", + "Thread": "Vlákno", + "Threads": "Vlákna", + "Title": "Název" + } +} diff --git a/plugins/chat-assets/lang/de.json b/plugins/chat-assets/lang/de.json new file mode 100644 index 00000000000..ef0a38a5948 --- /dev/null +++ b/plugins/chat-assets/lang/de.json @@ -0,0 +1,13 @@ +{ + "string": { + "Channel": "Kanal", + "Channels": "Kanäle", + "Chat": "Chat", + "Description": "Beschreibung", + "Loading": "Laden...", + "MessageIn": "Nachricht in #{title}", + "Thread": "Thread", + "Threads": "Threads", + "Title": "Titel" + } +} diff --git a/plugins/chat-assets/lang/en.json b/plugins/chat-assets/lang/en.json new file mode 100644 index 00000000000..149fe44e908 --- /dev/null +++ b/plugins/chat-assets/lang/en.json @@ -0,0 +1,13 @@ +{ + "string": { + "Channel": "Channel", + "Channels": "Channels", + "Chat": "Chat", + "Description": "Description", + "Loading": "Loading...", + "MessageIn": "Message #{title}", + "Thread": "Thread", + "Threads": "Threads", + "Title": "Title" + } +} \ No newline at end of file diff --git a/plugins/chat-assets/lang/es.json b/plugins/chat-assets/lang/es.json new file mode 100644 index 00000000000..30456a45b55 --- /dev/null +++ b/plugins/chat-assets/lang/es.json @@ -0,0 +1,13 @@ +{ + "string": { + "Channel": "Canal", + "Channels": "Canales", + "Chat": "Chat", + "Description": "Descripción", + "Loading": "Cargando...", + "MessageIn": "Mensaje en #{title}", + "Thread": "Hilo", + "Threads": "Hilos", + "Title": "Título" + } +} diff --git a/plugins/chat-assets/lang/fr.json b/plugins/chat-assets/lang/fr.json new file mode 100644 index 00000000000..572a3430bf2 --- /dev/null +++ b/plugins/chat-assets/lang/fr.json @@ -0,0 +1,13 @@ +{ + "string": { + "Channel": "Canal", + "Channels": "Canaux", + "Chat": "Chat", + "Description": "Description", + "Loading": "Chargement...", + "MessageIn": "Message dans #{title}", + "Thread": "Fil de discussion", + "Threads": "Fils de discussion", + "Title": "Titre" + } +} diff --git a/plugins/chat-assets/lang/it.json b/plugins/chat-assets/lang/it.json new file mode 100644 index 00000000000..5a214ce93bc --- /dev/null +++ b/plugins/chat-assets/lang/it.json @@ -0,0 +1,13 @@ +{ + "string": { + "Channel": "Canale", + "Channels": "Canali", + "Chat": "Chat", + "Description": "Descrizione", + "Loading": "Caricamento...", + "MessageIn": "Messaggio in #{title}", + "Thread": "Discussione", + "Threads": "Discussioni", + "Title": "Titolo" + } +} diff --git a/plugins/chat-assets/lang/pt.json b/plugins/chat-assets/lang/pt.json new file mode 100644 index 00000000000..7ba32b35c88 --- /dev/null +++ b/plugins/chat-assets/lang/pt.json @@ -0,0 +1,13 @@ +{ + "string": { + "Channel": "Canal", + "Channels": "Canais", + "Chat": "Chat", + "Description": "Descrição", + "Loading": "Carregando...", + "MessageIn": "Mensagem em #{title}", + "Thread": "Tópico", + "Threads": "Tópicos", + "Title": "Título" + } +} diff --git a/plugins/chat-assets/lang/ru.json b/plugins/chat-assets/lang/ru.json new file mode 100644 index 00000000000..a7e6f46d826 --- /dev/null +++ b/plugins/chat-assets/lang/ru.json @@ -0,0 +1,13 @@ +{ + "string": { + "Channel": "Канал", + "Channels": "Каналы", + "Chat": "Чат", + "Description": "Описание", + "Loading": "Загрузка...", + "MessageIn": "Сообщение в #{title}", + "Thread": "Тред", + "Threads": "Треды", + "Title": "Название" + } +} diff --git a/plugins/chat-assets/lang/zh.json b/plugins/chat-assets/lang/zh.json new file mode 100644 index 00000000000..f7b4afe1f37 --- /dev/null +++ b/plugins/chat-assets/lang/zh.json @@ -0,0 +1,13 @@ +{ + "string": { + "Channel": "频道", + "Channels": "频道", + "Chat": "聊天", + "Description": "描述", + "Loading": "加载中...", + "MessageIn": "在 #{title} 的消息", + "Thread": "讨论串", + "Threads": "讨论串", + "Title": "标题" + } +} diff --git a/plugins/chat-assets/package.json b/plugins/chat-assets/package.json new file mode 100644 index 00000000000..8ed71e4fca6 --- /dev/null +++ b/plugins/chat-assets/package.json @@ -0,0 +1,43 @@ +{ + "name": "@hcengineering/chat-assets", + "version": "0.6.0", + "main": "src/index.ts", + "author": "Hardcore Engineering Inc", + "template": "@hcengineering/assets-package", + "license": "EPL-2.0", + "scripts": { + "build": "compile", + "test": "jest --passWithNoTests --silent", + "build:docs": "", + "format": "format src", + "build:watch": "compile", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.4.0", + "eslint-plugin-promise": "^6.1.1", + "eslint": "^8.54.0", + "prettier": "^3.1.0", + "@types/node": "~20.11.16", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "typescript": "^5.3.3" + }, + "dependencies": { + "@hcengineering/platform": "^0.6.11", + "@hcengineering/chat": "^0.6.0" + }, + "repository": "https://github.com/hcenginneing/anticrm", + "publishConfig": { + "registry": "https://npm.pkg.github.com" + } +} diff --git a/plugins/chat-assets/src/__tests__/lang.test.ts b/plugins/chat-assets/src/__tests__/lang.test.ts new file mode 100644 index 00000000000..9098dbdab14 --- /dev/null +++ b/plugins/chat-assets/src/__tests__/lang.test.ts @@ -0,0 +1,21 @@ +// +// Copyright © 2025 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. +// + +import { makeLocalesTest } from '@hcengineering/platform' + +it( + 'Locales are equale', + makeLocalesTest((lang) => import(`../../lang/${lang}.json`)) +) diff --git a/plugins/chat-assets/src/index.ts b/plugins/chat-assets/src/index.ts new file mode 100644 index 00000000000..e06aa74fa06 --- /dev/null +++ b/plugins/chat-assets/src/index.ts @@ -0,0 +1,24 @@ +// +// Copyright © 2025 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. +// + +import { loadMetadata } from '@hcengineering/platform' +import chat from '@hcengineering/chat' + +const icons = require('../assets/icons.svg') as string // eslint-disable-line +loadMetadata(chat.icon, { + Channel: `${icons}#grid`, + ChatBubble: `${icons}#chat-bubble`, + Thread: `${icons}#message-multiple` +}) diff --git a/plugins/chat-assets/tsconfig.json b/plugins/chat-assets/tsconfig.json new file mode 100644 index 00000000000..4449c73536a --- /dev/null +++ b/plugins/chat-assets/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/assets/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "types": ["node", "jest"], + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/plugins/chat-resources/.eslintrc.js b/plugins/chat-resources/.eslintrc.js new file mode 100644 index 00000000000..bb8fd7450d4 --- /dev/null +++ b/plugins/chat-resources/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/ui/eslint.config.json'], + parserOptions: { tsconfigRootDir: __dirname } +} diff --git a/plugins/chat-resources/.prettierrc b/plugins/chat-resources/.prettierrc new file mode 100644 index 00000000000..792942803ac --- /dev/null +++ b/plugins/chat-resources/.prettierrc @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "trailingComma": "none", + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "printWidth": 120, + "useTabs": false, + "bracketSpacing": true, + "proseWrap": "preserve", + "plugins": [ + "prettier-plugin-svelte" + ], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} \ No newline at end of file diff --git a/plugins/chat-resources/config/rig.json b/plugins/chat-resources/config/rig.json new file mode 100644 index 00000000000..bcad6f7c33b --- /dev/null +++ b/plugins/chat-resources/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "ui" +} diff --git a/plugins/chat-resources/jest.config.js b/plugins/chat-resources/jest.config.js new file mode 100644 index 00000000000..3656e284d33 --- /dev/null +++ b/plugins/chat-resources/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'] +} diff --git a/plugins/chat-resources/package.json b/plugins/chat-resources/package.json new file mode 100644 index 00000000000..330d94c3c24 --- /dev/null +++ b/plugins/chat-resources/package.json @@ -0,0 +1,63 @@ +{ + "name": "@hcengineering/chat-resources", + "version": "0.6.0", + "main": "src/index.ts", + "author": "Hardcore Engineering Inc", + "license": "EPL-2.0", + "scripts": { + "build": "compile ui", + "build:docs": "api-extractor run --local", + "format": "format src", + "svelte-check": "do-svelte-check", + "_phase:svelte-check": "do-svelte-check", + "build:watch": "compile ui", + "_phase:build": "compile ui", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@types/jest": "^29.5.5", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint": "^8.54.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.4.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-svelte": "^2.35.1", + "jest": "^29.7.0", + "prettier": "^3.1.0", + "prettier-plugin-svelte": "^3.2.2", + "sass": "^1.53.0", + "svelte-check": "^3.6.9", + "svelte-eslint-parser": "^0.33.1", + "svelte-loader": "^3.2.0", + "svelte-preprocess": "^5.1.3", + "ts-jest": "^29.1.1", + "typescript": "^5.3.3" + }, + "dependencies": { + "@hcengineering/analytics": "^0.6.0", + "@hcengineering/card": "^0.6.0", + "@hcengineering/chat": "^0.6.0", + "@hcengineering/communication-types": "0.1.147", + "@hcengineering/contact": "^0.6.24", + "@hcengineering/contact-resources": "^0.6.0", + "@hcengineering/core": "^0.6.32", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/presence-resources": "^0.6.0", + "@hcengineering/presentation": "^0.6.3", + "@hcengineering/text": "^0.6.5", + "@hcengineering/text-markdown": "^0.6.0", + "@hcengineering/ui": "^0.6.15", + "@hcengineering/ui-next": "^0.6.0", + "@hcengineering/view": "^0.6.13", + "@hcengineering/view-resources": "^0.6.0", + "@hcengineering/workbench": "^0.6.16", + "@hcengineering/workbench-resources": "^0.6.1", + "@hcengineering/rank": "^0.6.4", + "fast-equals": "^5.2.2", + "svelte": "^4.2.19" + } +} diff --git a/plugins/chat-resources/postcss.config.js b/plugins/chat-resources/postcss.config.js new file mode 100644 index 00000000000..88752c6cb06 --- /dev/null +++ b/plugins/chat-resources/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: [ + require('autoprefixer') + ] +} diff --git a/plugins/chat-resources/src/actions.ts b/plugins/chat-resources/src/actions.ts new file mode 100644 index 00000000000..5b9b57b5116 --- /dev/null +++ b/plugins/chat-resources/src/actions.ts @@ -0,0 +1,22 @@ +// +// Copyright © 2025 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. +// + +import { type Message } from '@hcengineering/communication-types' + +import { openThreadInSidebar } from './location' + +export async function replyToThread (message: Message): Promise { + await openThreadInSidebar(message) +} diff --git a/plugins/chat-resources/src/components/ChatApplication.svelte b/plugins/chat-resources/src/components/ChatApplication.svelte new file mode 100644 index 00000000000..382e1c9d7fe --- /dev/null +++ b/plugins/chat-resources/src/components/ChatApplication.svelte @@ -0,0 +1,161 @@ + + + + +
+ {#if $deviceInfo.navigator.visible} +
+
+ +
+ {#if !($deviceInfo.isMobile && $deviceInfo.isPortrait && $deviceInfo.minWidth)} + + {/if} +
+ + {/if} +
+ {#if card} + {@const context = contexts.find((c) => c.card === card?._id)} + {#key card._id} + + {/key} + {/if} +
+
+ + diff --git a/plugins/chat-resources/src/components/ChatBody.svelte b/plugins/chat-resources/src/components/ChatBody.svelte new file mode 100644 index 00000000000..c90a30f580a --- /dev/null +++ b/plugins/chat-resources/src/components/ChatBody.svelte @@ -0,0 +1,309 @@ + + + + + + {#if card} + {#if window !== undefined && window.hasPrevPage()} + + {/if} + {#each groups as group (group.day.toString())} + {@const withSeparator = separatorDate != null && getGroupDay(separatorDate) === group.day} + {#if withSeparator} + + {:else} + + {/if} + {/each} + {#if window !== undefined && window.hasNextPage()} + + {/if} + + {#if footerHeight != null && footerHeight > 0} +
+ {/if} + {/if} + + + diff --git a/plugins/chat-resources/src/components/ChatFooter.svelte b/plugins/chat-resources/src/components/ChatFooter.svelte new file mode 100644 index 00000000000..e28c5a3dfee --- /dev/null +++ b/plugins/chat-resources/src/components/ChatFooter.svelte @@ -0,0 +1,52 @@ + + + + + + + diff --git a/plugins/chat-resources/src/components/ChatHeader.svelte b/plugins/chat-resources/src/components/ChatHeader.svelte new file mode 100644 index 00000000000..58e776395aa --- /dev/null +++ b/plugins/chat-resources/src/components/ChatHeader.svelte @@ -0,0 +1,33 @@ + + + + +
+ + diff --git a/plugins/chat-resources/src/components/ChatInput.svelte b/plugins/chat-resources/src/components/ChatInput.svelte new file mode 100644 index 00000000000..e4554f83304 --- /dev/null +++ b/plugins/chat-resources/src/components/ChatInput.svelte @@ -0,0 +1,25 @@ + + + + + diff --git a/plugins/chat-resources/src/components/ChatLoadingFiller.svelte b/plugins/chat-resources/src/components/ChatLoadingFiller.svelte new file mode 100644 index 00000000000..abe06b72ed9 --- /dev/null +++ b/plugins/chat-resources/src/components/ChatLoadingFiller.svelte @@ -0,0 +1,36 @@ + + + +
+
+ + diff --git a/plugins/chat-resources/src/components/ChatNavigation.svelte b/plugins/chat-resources/src/components/ChatNavigation.svelte new file mode 100644 index 00000000000..b41dbe3243e --- /dev/null +++ b/plugins/chat-resources/src/components/ChatNavigation.svelte @@ -0,0 +1,77 @@ + + + + + +
+ +
+
+ + diff --git a/plugins/chat-resources/src/components/ChatPanel.svelte b/plugins/chat-resources/src/components/ChatPanel.svelte new file mode 100644 index 00000000000..0b29427fe9d --- /dev/null +++ b/plugins/chat-resources/src/components/ChatPanel.svelte @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/plugins/chat-resources/src/components/ChatWidget.svelte b/plugins/chat-resources/src/components/ChatWidget.svelte new file mode 100644 index 00000000000..b6f94103280 --- /dev/null +++ b/plugins/chat-resources/src/components/ChatWidget.svelte @@ -0,0 +1,173 @@ + + + +{#if widget && data && data.message} +
+ + {#if message && parentCard} +
+ +
+ + +
+ +
+
+ +
+ {/if} +
+{/if} + + diff --git a/plugins/chat-resources/src/components/internal/ReverseScroller.svelte b/plugins/chat-resources/src/components/internal/ReverseScroller.svelte new file mode 100644 index 00000000000..34299ca2bac --- /dev/null +++ b/plugins/chat-resources/src/components/internal/ReverseScroller.svelte @@ -0,0 +1,58 @@ + + + +{#if isLoading} +
+ +
+{/if} + + + + + diff --git a/plugins/chat-resources/src/index.ts b/plugins/chat-resources/src/index.ts new file mode 100644 index 00000000000..7e09f715c71 --- /dev/null +++ b/plugins/chat-resources/src/index.ts @@ -0,0 +1,26 @@ +// +// Copyright © 2025 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. +// + +import { type Resources } from '@hcengineering/platform' + +import ChatApplication from './components/ChatApplication.svelte' +import ChatWidget from './components/ChatWidget.svelte' + +export default async (): Promise => ({ + component: { + ChatApplication, + ChatWidget + } +}) diff --git a/plugins/chat-resources/src/location.ts b/plugins/chat-resources/src/location.ts new file mode 100644 index 00000000000..6da63799bbc --- /dev/null +++ b/plugins/chat-resources/src/location.ts @@ -0,0 +1,63 @@ +// +// Copyright © 2025 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. +// + +import { type Card } from '@hcengineering/card' +import type { Ref } from '@hcengineering/core' +import { navigate, type Location, getCurrentResolvedLocation } from '@hcengineering/ui' +import { chatId } from '@hcengineering/chat' +import { getClient } from '@hcengineering/presentation' +import { type Message } from '@hcengineering/communication-types' +import workbench from '@hcengineering/workbench' +import { openWidget } from '@hcengineering/workbench-resources' + +import chat from './plugin' +import { type ChatWidgetData } from './types' + +// Url: /chat/{cardId}/{threadId}?message={messageId} + +export function getCardIdFromLocation (loc: Location): Ref | undefined { + if (loc.path[2] !== chatId) { + return undefined + } + return loc.path[3] as Ref +} + +export function navigateToCard (_id: Ref): void { + const loc = getCurrentResolvedLocation() + + loc.path[2] = chatId + loc.path[3] = _id + loc.path[4] = '' + loc.path.length = 4 + delete loc.query?.message + + navigate(loc) +} + +export async function openThreadInSidebar (message: Message): Promise { + const client = getClient() + + const widget = client.getModel().findAllSync(workbench.class.Widget, { _id: chat.ids.ChatWidget })[0] + if (widget === undefined) return + + const data: ChatWidgetData = { + id: `${message.card}-${message.id}`, + name: 'Thread', + message: message.id, + card: message.card as Ref + } + + openWidget(widget, data) +} diff --git a/plugins/chat-resources/src/navigator.ts b/plugins/chat-resources/src/navigator.ts new file mode 100644 index 00000000000..f184062f0e7 --- /dev/null +++ b/plugins/chat-resources/src/navigator.ts @@ -0,0 +1,147 @@ +// +// Copyright © 2025 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. +// + +import { type Card, type MasterTag } from '@hcengineering/card' +import { type NavigationSection } from '@hcengineering/ui-next' +import { groupByArray, type Hierarchy, type Ref } from '@hcengineering/core' +import chat from '@hcengineering/chat' +import { translate } from '@hcengineering/platform' +import { getClient } from '@hcengineering/presentation' +import { get, writable } from 'svelte/store' +import { type NotificationContext } from '@hcengineering/communication-types' + +const navigatorStateStorageKey = 'chat.navigatorState' + +export interface NavigatorState { + collapsedSections: string[] +} + +export const navigatorStateStore = writable(restoreNavigatorState()) + +function restoreNavigatorState (): NavigatorState { + const raw = localStorage.getItem(navigatorStateStorageKey) + + if (raw == null) return { collapsedSections: [] } + + try { + const parsed = JSON.parse(raw) + return { + collapsedSections: parsed.collapsedSections ?? [] + } + } catch (e) { + return { collapsedSections: [] } + } +} + +export function toggleSection (id: string): void { + const state = get(navigatorStateStore) + const result: NavigatorState = state.collapsedSections.includes(id) + ? { + ...state, + collapsedSections: state.collapsedSections.filter((it) => it !== id) + } + : { ...state, collapsedSections: [...state.collapsedSections, id] } + + localStorage.setItem(navigatorStateStorageKey, JSON.stringify(result)) + navigatorStateStore.set(result) +} + +export async function cardsToChatSections ( + cards: Card[], + contexts: NotificationContext[], + state: NavigatorState +): Promise { + const client = getClient() + const hierarchy = client.getHierarchy() + const { threads, channels, other } = splitCards(cards, hierarchy) + const cardByClass = groupByArray(other, (it) => it._class) + + const result: NavigationSection[] = [] + + if (threads.length > 0) { + result.push(getSection(chat.masterTag.Thread, threads, contexts, state, hierarchy)) + } + + if (channels.length > 0) { + result.push(getSection(chat.masterTag.Channel, channels, contexts, state, hierarchy)) + } + + const cardSessions: Array<[string, NavigationSection]> = [] + for (const [_class, cards] of cardByClass.entries()) { + const section = getSection(_class, cards, contexts, state, hierarchy) + const label = await translate(section.title, {}) + cardSessions.push([label, section]) + } + + cardSessions.sort((a, b) => a[0].toLowerCase().localeCompare(b[0].toLowerCase())) + + result.push(...cardSessions.map(([, section]) => section)) + + return result +} + +function getSection ( + _class: Ref, + cards: Card[], + contexts: NotificationContext[], + state: NavigatorState, + hierarchy: Hierarchy +): NavigationSection { + const clazz = hierarchy.getClass(_class) + + return { + id: _class, + title: clazz.pluralLabel ?? clazz.label, + expanded: !state.collapsedSections.includes(_class), + items: cards + .map((card) => { + const context = contexts.find((it) => it.card === card._id) + return { + id: card._id, + label: card.title, + icon: clazz.icon ?? chat.icon.Thread, + notificationsCount: context?.notifications?.length ?? 0 + } + }) + .sort((c1, c2) => c1.label.toLowerCase().localeCompare(c2.label.toLowerCase())) + } +} + +function splitCards ( + cards: Card[], + hierarchy: Hierarchy +): { + threads: Card[] + channels: Card[] + other: Card[] + } { + return cards.reduce<{ + threads: Card[] + channels: Card[] + other: Card[] + }>( + (acc, it) => { + if (hierarchy.isDerived(it._class, chat.masterTag.Thread)) { + acc.threads.push(it) + } else if (hierarchy.isDerived(it._class, chat.masterTag.Channel)) { + acc.channels.push(it) + } else { + acc.other.push(it) + } + return acc + }, + { threads: [], channels: [], other: [] } + ) +} diff --git a/plugins/chat-resources/src/plugin.ts b/plugins/chat-resources/src/plugin.ts new file mode 100644 index 00000000000..418c6207060 --- /dev/null +++ b/plugins/chat-resources/src/plugin.ts @@ -0,0 +1,25 @@ +// +// Copyright © 2025 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. +// + +import chat, { chatId } from '@hcengineering/chat' +import { mergeIds } from '@hcengineering/platform' +import type { AnyComponent } from '@hcengineering/ui' + +export default mergeIds(chatId, chat, { + component: { + ChatApplication: '' as AnyComponent, + ChatWidget: '' as AnyComponent + } +}) diff --git a/plugins/chat-resources/src/types.ts b/plugins/chat-resources/src/types.ts new file mode 100644 index 00000000000..40027c94ae9 --- /dev/null +++ b/plugins/chat-resources/src/types.ts @@ -0,0 +1,26 @@ +// +// Copyright © 2025 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. +// + +import type { Ref } from '@hcengineering/core' +import type { Card } from '@hcengineering/card' +import { type MessageID } from '@hcengineering/communication-types' + +export interface ChatWidgetData { + id: string + card: Ref + name: string + message?: MessageID + thread?: Ref +} diff --git a/plugins/chat-resources/src/ui.ts b/plugins/chat-resources/src/ui.ts new file mode 100644 index 00000000000..af6ca83bae3 --- /dev/null +++ b/plugins/chat-resources/src/ui.ts @@ -0,0 +1,94 @@ +// +// Copyright © 2025 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. +// + +import { type Message } from '@hcengineering/communication-types' + +export interface MessagesGroup { + day: number + messages: Message[] +} + +export function getGroupDay (date: Date): number { + return new Date(date).setHours(0, 0, 0, 0) +} +export function groupMessagesByDay (messages: Message[]): MessagesGroup[] { + const result: MessagesGroup[] = [] + + for (const message of messages) { + const day = getGroupDay(message.created) + const group = findOrCreateGroup(result, day, (group) => result.push(group)) + group.messages.push(message) + } + + return result +} + +function findOrCreateGroup ( + groups: MessagesGroup[], + dayTimestamp: number, + pushFn: (group: MessagesGroup) => void +): MessagesGroup { + let group = groups.find((g) => g.day === dayTimestamp) + + if (group === undefined) { + group = { day: dayTimestamp, messages: [] } + pushFn(group) + } + + return group +} + +export function createMessagesObserver ( + contentDiv: HTMLDivElement, + onMessageView: (node: HTMLDivElement) => void +): void { + const messageObserver = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + onMessageView(entry.target as HTMLDivElement) + messageObserver.unobserve(entry.target) + } + }) + }, + { + root: null, + rootMargin: '-150px 0px -120px 0px', + threshold: 0.1 + } + ) + + contentDiv.querySelectorAll('.message').forEach((message) => { + messageObserver.observe(message) + }) + + const mutationObserver = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + mutation.addedNodes.forEach((node: Node) => { + const element = node as HTMLDivElement + if (element.classList?.contains('messages-group')) { + element.querySelectorAll('.message').forEach((message) => { + messageObserver.observe(message) + }) + } + if (element.classList?.contains('message')) { + messageObserver.observe(element) + } + }) + }) + }) + + mutationObserver.observe(contentDiv, { childList: true, subtree: true }) +} diff --git a/plugins/chat-resources/svelte.config.js b/plugins/chat-resources/svelte.config.js new file mode 100644 index 00000000000..944a06f73ee --- /dev/null +++ b/plugins/chat-resources/svelte.config.js @@ -0,0 +1,5 @@ +const sveltePreprocess = require('svelte-preprocess') + +module.exports = { + preprocess: sveltePreprocess() +}; \ No newline at end of file diff --git a/plugins/chat-resources/tsconfig.json b/plugins/chat-resources/tsconfig.json new file mode 100644 index 00000000000..fb6ccb2d182 --- /dev/null +++ b/plugins/chat-resources/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/ui/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types" + } +} \ No newline at end of file diff --git a/plugins/chat/.eslintrc.js b/plugins/chat/.eslintrc.js new file mode 100644 index 00000000000..72235dc2833 --- /dev/null +++ b/plugins/chat/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/plugins/chat/.npmignore b/plugins/chat/.npmignore new file mode 100644 index 00000000000..e3ec093c383 --- /dev/null +++ b/plugins/chat/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/plugins/chat/config/rig.json b/plugins/chat/config/rig.json new file mode 100644 index 00000000000..0110930f55e --- /dev/null +++ b/plugins/chat/config/rig.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig" +} diff --git a/plugins/chat/jest.config.js b/plugins/chat/jest.config.js new file mode 100644 index 00000000000..2cfd408b679 --- /dev/null +++ b/plugins/chat/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/plugins/chat/package.json b/plugins/chat/package.json new file mode 100644 index 00000000000..8f2daef06a6 --- /dev/null +++ b/plugins/chat/package.json @@ -0,0 +1,49 @@ +{ + "name": "@hcengineering/chat", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "files": [ + "lib/**/*", + "types/**/*", + "tsconfig.json" + ], + "author": "Hardcore Engineering Inc", + "license": "EPL-2.0", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "test": "jest --passWithNoTests --silent", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "typescript": "^5.3.3", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5" + }, + "dependencies": { + "@hcengineering/core": "^0.6.32", + "@hcengineering/card": "^0.6.0", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/workbench": "^0.6.16" + }, + "repository": "https://github.com/hcengineering/platform", + "publishConfig": { + "registry": "https://npm.pkg.github.com" + } +} diff --git a/plugins/chat/src/index.ts b/plugins/chat/src/index.ts new file mode 100644 index 00000000000..726091ad79d --- /dev/null +++ b/plugins/chat/src/index.ts @@ -0,0 +1,49 @@ +// +// Copyright © 2025 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. +// + +import { Ref } from '@hcengineering/core' +import { plugin, IntlString, type Plugin, Asset } from '@hcengineering/platform' +import { MasterTag } from '@hcengineering/card' +import { Widget } from '@hcengineering/workbench' + +export const chatId = 'chat' as Plugin + +const chat = plugin(chatId, { + string: { + Channel: '' as IntlString, + Channels: '' as IntlString, + Chat: '' as IntlString, + Description: '' as IntlString, + Loading: '' as IntlString, + MessageIn: '' as IntlString, + Thread: '' as IntlString, + Threads: '' as IntlString, + Title: '' as IntlString + }, + icon: { + Channel: '' as Asset, + ChatBubble: '' as Asset, + Thread: '' as Asset + }, + masterTag: { + Channel: '' as Ref, + Thread: '' as Ref + }, + ids: { + ChatWidget: '' as Ref + } +}) + +export default chat diff --git a/plugins/chat/tsconfig.json b/plugins/chat/tsconfig.json new file mode 100644 index 00000000000..59e4fd42978 --- /dev/null +++ b/plugins/chat/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/plugins/client-resources/package.json b/plugins/client-resources/package.json index 443ae5a98f1..7c4450b320b 100644 --- a/plugins/client-resources/package.json +++ b/plugins/client-resources/package.json @@ -39,9 +39,11 @@ }, "dependencies": { "@hcengineering/analytics": "^0.6.0", - "@hcengineering/platform": "^0.6.11", - "@hcengineering/core": "^0.6.32", "@hcengineering/client": "^0.6.18", + "@hcengineering/communication-sdk-types": "0.1.147", + "@hcengineering/communication-types": "0.1.147", + "@hcengineering/core": "^0.6.32", + "@hcengineering/platform": "^0.6.11", "@hcengineering/rpc": "^0.6.5", "snappyjs": "^0.7.0" }, diff --git a/plugins/client-resources/src/connection.ts b/plugins/client-resources/src/connection.ts index f68fbc5b80a..1216a66ad18 100644 --- a/plugins/client-resources/src/connection.ts +++ b/plugins/client-resources/src/connection.ts @@ -16,52 +16,62 @@ import { Analytics } from '@hcengineering/analytics' import client, { + type ClientFactoryOptions, ClientSocket, ClientSocketReadyState, pingConst, - pongConst, - type ClientFactoryOptions + pongConst } from '@hcengineering/client' import core, { Account, Class, ClientConnectEvent, ClientConnection, + clone, + Handler, Doc, DocChunk, DocumentQuery, Domain, FindOptions, FindResult, + generateId, LoadModelResponse, + type MeasureContext, MeasureMetricsContext, + type PersonUuid, Ref, SearchOptions, SearchQuery, SearchResult, Timestamp, + toFindResult, Tx, TxApplyIf, TxHandler, TxResult, - clone, - generateId, - toFindResult, - type MeasureContext, - type PersonUuid, type WorkspaceUuid } from '@hcengineering/core' import platform, { + broadcastEvent, + getMetadata, PlatformError, Severity, Status, - UNAUTHORIZED, - broadcastEvent, - getMetadata + UNAUTHORIZED } from '@hcengineering/platform' import { uncompress } from 'snappyjs' - -import { HelloRequest, HelloResponse, RPCHandler, ReqId, type Response } from '@hcengineering/rpc' +import { HelloRequest, HelloResponse, ReqId, type Response, RPCHandler } from '@hcengineering/rpc' +import { EventResult } from '@hcengineering/communication-sdk-types' +import { + FindMessagesGroupsParams, + FindMessagesParams, + FindNotificationContextParams, + FindNotificationsParams, + Message, + MessagesGroup, + NotificationContext +} from '@hcengineering/communication-types' const SECOND = 1000 const pingTimeout = 10 * SECOND @@ -123,10 +133,12 @@ class Connection implements ClientConnection { lastHash?: string + handlers: Handler[] = [] + constructor ( private readonly ctx: MeasureContext, private readonly url: string, - private readonly handler: TxHandler, + handler: TxHandler, readonly workspace: WorkspaceUuid, readonly user: PersonUuid, readonly opt?: ClientFactoryOptions @@ -150,12 +162,16 @@ class Connection implements ClientConnection { this.sessionId = generateId() } this.rpcHandler = opt?.useGlobalRPCHandler === true ? globalRPCHandler : new RPCHandler() - + this.pushHandler(handler) this.onConnect = opt?.onConnect this.scheduleOpen(this.ctx, false) } + pushHandler (handler: Handler): void { + this.handlers.push(handler) + } + async getLastHash (ctx: MeasureContext): Promise { await this.waitOpenConnection(ctx) return this.lastHash @@ -455,7 +471,9 @@ class Connection implements ClientConnection { return } } - this.handler(...txArr) + this.handlers.forEach((handler) => { + handler(...txArr) + }) clearTimeout(this.incomingTimer) void broadcastEvent(client.event.NetworkRequests, this.requests.size + 1).catch((err) => { @@ -843,6 +861,33 @@ class Connection implements ClientConnection { sendForceClose (): Promise { return this.sendRequest({ method: 'forceClose', params: [], allowReconnect: false, overrideId: -2, once: true }) } + + async sendEvent (event: Event): Promise { + return await this.sendRequest({ method: 'event', params: [event] }) + } + + async findMessages (params: FindMessagesParams, queryId?: number): Promise { + return await this.sendRequest({ method: 'findMessages', params: [params, queryId] }) + } + + async findMessagesGroups (params: FindMessagesGroupsParams): Promise { + return await this.sendRequest({ method: 'findMessagesGroups', params: [params] }) + } + + async findNotificationContexts ( + params: FindNotificationContextParams, + queryId?: number + ): Promise { + return await this.sendRequest({ method: 'findNotificationContexts', params: [params, queryId] }) + } + + async findNotifications (params: FindNotificationsParams, queryId?: number): Promise { + return await this.sendRequest({ method: 'findNotifications', params: [params, queryId] }) + } + + async unsubscribeQuery (id: number): Promise { + await this.sendRequest({ method: 'unsubscribeQuery', params: [id] }) + } } /** diff --git a/plugins/contact-resources/src/components/Avatar.svelte b/plugins/contact-resources/src/components/Avatar.svelte index 8aa559310c5..c0cd14a13c0 100644 --- a/plugins/contact-resources/src/components/Avatar.svelte +++ b/plugins/contact-resources/src/components/Avatar.svelte @@ -12,38 +12,30 @@ // See the License for the specific language governing permissions and // limitations under the License. --> - + +
+ {#if $deviceInfo.navigator.visible} +
+
+ +
+ {#if !($deviceInfo.isMobile && $deviceInfo.isPortrait && $deviceInfo.minWidth)} + + {/if} +
+ + {/if} +
+ {#if card} + {@const panel = client.getHierarchy().classHierarchyMixin(card._class, view.mixin.ObjectPanel)} + + {/if} +
+
+ + diff --git a/plugins/inbox-resources/src/components/InboxCard.svelte b/plugins/inbox-resources/src/components/InboxCard.svelte new file mode 100644 index 00000000000..7eb6ffcd9e7 --- /dev/null +++ b/plugins/inbox-resources/src/components/InboxCard.svelte @@ -0,0 +1,120 @@ + + + + + + +
{ + dispatch('select', { context, card }) + }} +> +
+ !x.read)?.length ?? 0} /> +
+ + {card.title} + +
+
+
+
+ {#each displayNotifications as notification (notification.messageId)} + + {/each} +
+
+
+ + diff --git a/plugins/inbox-resources/src/components/InboxCardIcon.svelte b/plugins/inbox-resources/src/components/InboxCardIcon.svelte new file mode 100644 index 00000000000..1a4bb896e30 --- /dev/null +++ b/plugins/inbox-resources/src/components/InboxCardIcon.svelte @@ -0,0 +1,64 @@ + + + + +
+ {#if icon} + + {/if} + +
+ +
+
+ + diff --git a/plugins/inbox-resources/src/components/InboxNavigation.svelte b/plugins/inbox-resources/src/components/InboxNavigation.svelte new file mode 100644 index 00000000000..fe6c33ac957 --- /dev/null +++ b/plugins/inbox-resources/src/components/InboxNavigation.svelte @@ -0,0 +1,90 @@ + + + + + +
+ {#each contexts as context (context.id)} + {@const contextCard = cards.find((c) => c._id === context.card)} + {#if contextCard} + + {/if} + {/each} +
+
+ + diff --git a/plugins/inbox-resources/src/components/InboxNotification.svelte b/plugins/inbox-resources/src/components/InboxNotification.svelte new file mode 100644 index 00000000000..f55f96a5a0a --- /dev/null +++ b/plugins/inbox-resources/src/components/InboxNotification.svelte @@ -0,0 +1,37 @@ + + + + +{#if notification.message} +
+ +
+{/if} + + diff --git a/plugins/inbox-resources/src/components/NotifyMarker.svelte b/plugins/inbox-resources/src/components/NotifyMarker.svelte new file mode 100644 index 00000000000..b9cf69670a5 --- /dev/null +++ b/plugins/inbox-resources/src/components/NotifyMarker.svelte @@ -0,0 +1,74 @@ + + + +{#if kind === 'primary' && count > 0} +
+ {#if count > maxNumber} + {maxNumber}+ + {:else} + {count} + {/if} +
+{/if} + +{#if kind === 'simple'} +
+{/if} + + diff --git a/plugins/inbox-resources/src/index.ts b/plugins/inbox-resources/src/index.ts new file mode 100644 index 00000000000..3484325d51c --- /dev/null +++ b/plugins/inbox-resources/src/index.ts @@ -0,0 +1,24 @@ +// +// Copyright © 2025 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. +// + +import { type Resources } from '@hcengineering/platform' + +import InboxApplication from './components/InboxApplication.svelte' + +export default async (): Promise => ({ + component: { + InboxApplication + } +}) diff --git a/plugins/inbox-resources/src/location.ts b/plugins/inbox-resources/src/location.ts new file mode 100644 index 00000000000..c20d39dfdea --- /dev/null +++ b/plugins/inbox-resources/src/location.ts @@ -0,0 +1,37 @@ +// +// Copyright © 2025 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. +// + +import { type Card } from '@hcengineering/card' +import type { Ref } from '@hcengineering/core' +import { navigate, type Location, getCurrentResolvedLocation } from '@hcengineering/ui' +import { inboxId } from '@hcengineering/inbox' + +// Url: /inbox/{cardId} + +export function getCardIdFromLocation (loc: Location): Ref | undefined { + if (loc.path[2] !== inboxId) { + return undefined + } + return loc.path[3] as Ref +} + +export function navigateToCard (_id: Ref): void { + const loc = getCurrentResolvedLocation() + + loc.path[2] = inboxId + loc.path[3] = _id + + navigate(loc) +} diff --git a/plugins/inbox-resources/src/plugin.ts b/plugins/inbox-resources/src/plugin.ts new file mode 100644 index 00000000000..f7504f64894 --- /dev/null +++ b/plugins/inbox-resources/src/plugin.ts @@ -0,0 +1,24 @@ +// +// Copyright © 2025 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. +// + +import inbox, { inboxId } from '@hcengineering/inbox' +import { mergeIds } from '@hcengineering/platform' +import type { AnyComponent } from '@hcengineering/ui' + +export default mergeIds(inboxId, inbox, { + component: { + InboxApplication: '' as AnyComponent + } +}) diff --git a/plugins/inbox-resources/svelte.config.js b/plugins/inbox-resources/svelte.config.js new file mode 100644 index 00000000000..944a06f73ee --- /dev/null +++ b/plugins/inbox-resources/svelte.config.js @@ -0,0 +1,5 @@ +const sveltePreprocess = require('svelte-preprocess') + +module.exports = { + preprocess: sveltePreprocess() +}; \ No newline at end of file diff --git a/plugins/inbox-resources/tsconfig.json b/plugins/inbox-resources/tsconfig.json new file mode 100644 index 00000000000..fb6ccb2d182 --- /dev/null +++ b/plugins/inbox-resources/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/ui/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types" + } +} \ No newline at end of file diff --git a/plugins/inbox/.eslintrc.js b/plugins/inbox/.eslintrc.js new file mode 100644 index 00000000000..72235dc2833 --- /dev/null +++ b/plugins/inbox/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/plugins/inbox/.npmignore b/plugins/inbox/.npmignore new file mode 100644 index 00000000000..e3ec093c383 --- /dev/null +++ b/plugins/inbox/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/plugins/inbox/config/rig.json b/plugins/inbox/config/rig.json new file mode 100644 index 00000000000..0110930f55e --- /dev/null +++ b/plugins/inbox/config/rig.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig" +} diff --git a/plugins/inbox/jest.config.js b/plugins/inbox/jest.config.js new file mode 100644 index 00000000000..2cfd408b679 --- /dev/null +++ b/plugins/inbox/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/plugins/inbox/package.json b/plugins/inbox/package.json new file mode 100644 index 00000000000..07be1fd4982 --- /dev/null +++ b/plugins/inbox/package.json @@ -0,0 +1,47 @@ +{ + "name": "@hcengineering/inbox", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "files": [ + "lib/**/*", + "types/**/*", + "tsconfig.json" + ], + "author": "Hardcore Engineering Inc", + "license": "EPL-2.0", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "test": "jest --passWithNoTests --silent", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "typescript": "^5.3.3", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5" + }, + "dependencies": { + "@hcengineering/core": "^0.6.32", + "@hcengineering/platform": "^0.6.11" + }, + "repository": "https://github.com/hcengineering/platform", + "publishConfig": { + "registry": "https://npm.pkg.github.com" + } +} diff --git a/plugins/inbox/src/index.ts b/plugins/inbox/src/index.ts new file mode 100644 index 00000000000..b7e188ae916 --- /dev/null +++ b/plugins/inbox/src/index.ts @@ -0,0 +1,29 @@ +// +// Copyright © 2025 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. +// + +import { Asset, IntlString, type Plugin, plugin } from '@hcengineering/platform' + +export const inboxId = 'inbox' as Plugin + +const inbox = plugin(inboxId, { + string: { + Inbox: '' as IntlString + }, + icon: { + Inbox: '' as Asset + } +}) + +export default inbox diff --git a/plugins/inbox/tsconfig.json b/plugins/inbox/tsconfig.json new file mode 100644 index 00000000000..59e4fd42978 --- /dev/null +++ b/plugins/inbox/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/plugins/recruit-resources/src/components/SkillsView.svelte b/plugins/recruit-resources/src/components/SkillsView.svelte index 643b8928cf6..e7d410c88eb 100644 --- a/plugins/recruit-resources/src/components/SkillsView.svelte +++ b/plugins/recruit-resources/src/components/SkillsView.svelte @@ -45,7 +45,7 @@ icon: recruit.icon.Skills, item: recruit.string.SkillLabel, key: 'skills', - сreateItemLabel: recruit.string.SkillCreateLabel, + createItemLabel: recruit.string.SkillCreateLabel, onTag }} > diff --git a/plugins/tags-resources/src/components/TagsView.svelte b/plugins/tags-resources/src/components/TagsView.svelte index 7c318ff84bd..e7ed1280c20 100644 --- a/plugins/tags-resources/src/components/TagsView.svelte +++ b/plugins/tags-resources/src/components/TagsView.svelte @@ -37,7 +37,7 @@ export let title: IntlString = tags.string.Tags export let icon: Asset | AnySvelteComponent = tags.icon.Tags export let item: IntlString = tags.string.Tag - export let сreateItemLabel: IntlString = tags.string.TagCreateLabel + export let createItemLabel: IntlString = tags.string.TagCreateLabel export let targetClass: Ref> export let onTag: ((tag: TagElement) => void) | undefined = undefined @@ -111,7 +111,7 @@ -