UBER-853 Move documents to Uberflow (#3700)

Signed-off-by: Alexander Onnikov <alexander.onnikov@xored.com>
This commit is contained in:
Alexander Onnikov
2023-09-15 15:31:24 +07:00
committed by GitHub
parent b61b47a4c3
commit 2d16709ccb
78 changed files with 10 additions and 3356 deletions
-16
View File
@@ -146,22 +146,6 @@
"sourceMaps": true,
"cwd": "${workspaceRoot}/dev/tool"
},
{
"name": "Debug Collaborator",
"type": "node",
"request": "launch",
"args": ["src/__start.ts"],
"env": {
"SECRET": "secret",
"MINIO_ACCESS_KEY": "minioadmin",
"MINIO_SECRET_KEY": "minioadmin",
"MINIO_ENDPOINT": "localhost"
},
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
"sourceMaps": true,
"cwd": "${workspaceRoot}/pods/collaborator",
"protocol": "inspector"
},
{
"name": "Debug backup",
"type": "node",
+10 -158
View File
@@ -41,9 +41,6 @@ specifiers:
'@rush-temp/dev-storage': file:./projects/dev-storage.tgz
'@rush-temp/devmodel': file:./projects/devmodel.tgz
'@rush-temp/devmodel-resources': file:./projects/devmodel-resources.tgz
'@rush-temp/document': file:./projects/document.tgz
'@rush-temp/document-assets': file:./projects/document-assets.tgz
'@rush-temp/document-resources': file:./projects/document-resources.tgz
'@rush-temp/elastic': file:./projects/elastic.tgz
'@rush-temp/front': file:./projects/front.tgz
'@rush-temp/generator': file:./projects/generator.tgz
@@ -78,7 +75,6 @@ specifiers:
'@rush-temp/model-chunter': file:./projects/model-chunter.tgz
'@rush-temp/model-contact': file:./projects/model-contact.tgz
'@rush-temp/model-core': file:./projects/model-core.tgz
'@rush-temp/model-document': file:./projects/model-document.tgz
'@rush-temp/model-gmail': file:./projects/model-gmail.tgz
'@rush-temp/model-hr': file:./projects/model-hr.tgz
'@rush-temp/model-inventory': file:./projects/model-inventory.tgz
@@ -129,7 +125,6 @@ specifiers:
'@rush-temp/platform-rig': file:./projects/platform-rig.tgz
'@rush-temp/pod-account': file:./projects/pod-account.tgz
'@rush-temp/pod-backup': file:./projects/pod-backup.tgz
'@rush-temp/pod-collaborator': file:./projects/pod-collaborator.tgz
'@rush-temp/pod-front': file:./projects/pod-front.tgz
'@rush-temp/pod-server': file:./projects/pod-server.tgz
'@rush-temp/preference': file:./projects/preference.tgz
@@ -334,7 +329,6 @@ specifiers:
koa-bodyparser: ^4.3.0
koa-router: ^10.1.1
lexorank: ~1.0.4
lib0: ~0.2.52
libphonenumber-js: ^1.9.46
mime-types: ~2.1.34
mini-css-extract-plugin: ^2.2.0
@@ -394,7 +388,6 @@ specifiers:
ws: ^8.10.0
xml2js: ~0.4.23
y-prosemirror: ^1.2.1
y-protocols: ^1.0.5
y-websocket: ^1.5.0
yjs: ^13.5.52
@@ -439,9 +432,6 @@ dependencies:
'@rush-temp/dev-storage': file:projects/dev-storage.tgz
'@rush-temp/devmodel': file:projects/devmodel.tgz_typescript@4.8.4
'@rush-temp/devmodel-resources': file:projects/devmodel-resources.tgz_ed2e4f4d904d50838e5f15c036f084b4
'@rush-temp/document': file:projects/document.tgz
'@rush-temp/document-assets': file:projects/document-assets.tgz_typescript@4.8.4
'@rush-temp/document-resources': file:projects/document-resources.tgz_a1d864769aaf53d09b76fe134ab55e60
'@rush-temp/elastic': file:projects/elastic.tgz_@types+node@16.11.68
'@rush-temp/front': file:projects/front.tgz
'@rush-temp/generator': file:projects/generator.tgz_bufferutil@4.0.7
@@ -476,7 +466,6 @@ dependencies:
'@rush-temp/model-chunter': file:projects/model-chunter.tgz_typescript@4.8.4
'@rush-temp/model-contact': file:projects/model-contact.tgz_typescript@4.8.4
'@rush-temp/model-core': file:projects/model-core.tgz_typescript@4.8.4
'@rush-temp/model-document': file:projects/model-document.tgz_typescript@4.8.4
'@rush-temp/model-gmail': file:projects/model-gmail.tgz_typescript@4.8.4
'@rush-temp/model-hr': file:projects/model-hr.tgz_typescript@4.8.4
'@rush-temp/model-inventory': file:projects/model-inventory.tgz_typescript@4.8.4
@@ -527,7 +516,6 @@ dependencies:
'@rush-temp/platform-rig': file:projects/platform-rig.tgz_c5e43dc15df4ac7868d10b0872442df4
'@rush-temp/pod-account': file:projects/pod-account.tgz
'@rush-temp/pod-backup': file:projects/pod-backup.tgz
'@rush-temp/pod-collaborator': file:projects/pod-collaborator.tgz_bufferutil@4.0.7
'@rush-temp/pod-front': file:projects/pod-front.tgz
'@rush-temp/pod-server': file:projects/pod-server.tgz
'@rush-temp/preference': file:projects/preference.tgz
@@ -605,7 +593,7 @@ dependencies:
'@rush-temp/templates-resources': file:projects/templates-resources.tgz_a1d864769aaf53d09b76fe134ab55e60
'@rush-temp/tests-sanity': file:projects/tests-sanity.tgz
'@rush-temp/text': file:projects/text.tgz_a7abb371f17d2bc77abec7bc53398db5
'@rush-temp/text-editor': file:projects/text-editor.tgz_1e646fd62a3adc9d0b41f256dafe3d38
'@rush-temp/text-editor': file:projects/text-editor.tgz_a1d864769aaf53d09b76fe134ab55e60
'@rush-temp/theme': file:projects/theme.tgz_a1d864769aaf53d09b76fe134ab55e60
'@rush-temp/tool': file:projects/tool.tgz_bufferutil@4.0.7
'@rush-temp/tracker': file:projects/tracker.tgz
@@ -732,7 +720,6 @@ dependencies:
koa-bodyparser: 4.3.0
koa-router: 10.1.1
lexorank: 1.0.5
lib0: 0.2.53
libphonenumber-js: 1.10.14
mime-types: 2.1.35
mini-css-extract-plugin: 2.6.1_webpack@5.75.0
@@ -791,8 +778,7 @@ dependencies:
webpack-dev-server: 4.11.1_5f7427e5f586f1bfc73e23d8c6331293
ws: 8.11.0_bufferutil@4.0.7
xml2js: 0.4.23
y-prosemirror: 1.2.1_4b437ae61db91263defb65d2247376eb
y-protocols: 1.0.5
y-prosemirror: 1.2.1_709ebdfd1c5bc23c335c8dea11286d09
y-websocket: 1.5.0_yjs@13.5.52
yjs: 13.5.52
@@ -6365,7 +6351,7 @@ packages:
y-prosemirror: 1.0.20
dependencies:
'@tiptap/core': 2.0.3_@tiptap+pm@2.0.3
y-prosemirror: 1.2.1_4b437ae61db91263defb65d2247376eb
y-prosemirror: 1.2.1_709ebdfd1c5bc23c335c8dea11286d09
dev: false
/@tiptap/extension-collaboration/2.0.3_9d93b21d48f6156ab534bd7bbcc15ccc:
@@ -6377,7 +6363,7 @@ packages:
dependencies:
'@tiptap/core': 2.0.3_@tiptap+pm@2.0.3
'@tiptap/pm': 2.0.3_@tiptap+core@2.0.3
y-prosemirror: 1.2.1_4b437ae61db91263defb65d2247376eb
y-prosemirror: 1.2.1_709ebdfd1c5bc23c335c8dea11286d09
dev: false
/@tiptap/extension-document/2.0.3_@tiptap+core@2.0.3:
@@ -17134,7 +17120,7 @@ packages:
dev: false
optional: true
/y-prosemirror/1.2.1_4b437ae61db91263defb65d2247376eb:
/y-prosemirror/1.2.1_709ebdfd1c5bc23c335c8dea11286d09:
resolution: {integrity: sha512-czMBfB1eL2awqmOSxQM8cS/fsUOGE6fjvyPLInrh4crPxFiw67wDpwIW+EGBYKRa04sYbS0ScGj7ZgvWuDrmBQ==}
peerDependencies:
prosemirror-model: ^1.7.1
@@ -17147,7 +17133,6 @@ packages:
prosemirror-model: 1.19.2
prosemirror-state: 1.4.3
prosemirror-view: 1.31.4
y-protocols: 1.0.5
yjs: 13.5.52
dev: false
@@ -18123,82 +18108,6 @@ packages:
- typescript
dev: false
file:projects/document-assets.tgz_typescript@4.8.4:
resolution: {integrity: sha512-O2pojKbUHyYRybsghngPaWxbgKhXwf9mf5aNSOSb+Kj04bERRLmle3fW59SaTAuqQw2efYKbfLO9baeVzQSp1A==, tarball: file:projects/document-assets.tgz}
id: file:projects/document-assets.tgz
name: '@rush-temp/document-assets'
version: 0.0.0
dependencies:
'@rushstack/heft': 0.47.11
'@types/heft-jest': 1.0.3
'@types/node': 16.11.68
'@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464
'@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4
eslint: 8.27.0
eslint-config-standard-with-typescript: 23.0.0_c9fe9619f50f4e82337a86c3af25e566
eslint-plugin-import: 2.26.0_eslint@8.27.0
eslint-plugin-n: 15.5.1_eslint@8.27.0
eslint-plugin-promise: 6.1.1_eslint@8.27.0
prettier: 2.8.8
transitivePeerDependencies:
- supports-color
- typescript
dev: false
file:projects/document-resources.tgz_a1d864769aaf53d09b76fe134ab55e60:
resolution: {integrity: sha512-qvUetpakwin4/2798Kzg0mZYjTOxzszP2okTsYE0/10yCECZ1q+m+CmPhYZqsnOdKJVxr1GiYSUluWmeXeI+ig==, tarball: file:projects/document-resources.tgz}
id: file:projects/document-resources.tgz
name: '@rush-temp/document-resources'
version: 0.0.0
dependencies:
'@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464
'@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4
eslint: 8.27.0
eslint-config-standard-with-typescript: 23.0.0_c9fe9619f50f4e82337a86c3af25e566
eslint-plugin-import: 2.26.0_eslint@8.27.0
eslint-plugin-n: 15.5.1_eslint@8.27.0
eslint-plugin-promise: 6.1.1_eslint@8.27.0
eslint-plugin-svelte3: 4.0.0_eslint@8.27.0+svelte@3.55.1
prettier: 2.8.8
prettier-plugin-svelte: 2.8.0_prettier@2.8.8+svelte@3.55.1
sass: 1.56.1
svelte: 3.55.1
svelte-check: 3.2.0_ae2e9904602215f07e0b815d3fa1ffe9
svelte-loader: 3.1.4_svelte@3.55.1
svelte-preprocess: 5.0.3_6420a3eba9d5580d9c2f627c17e61722
typescript: 4.8.4
transitivePeerDependencies:
- '@babel/core'
- coffeescript
- less
- postcss
- postcss-load-config
- pug
- stylus
- sugarss
- supports-color
dev: false
file:projects/document.tgz:
resolution: {integrity: sha512-JLRtzVrQ7j6bnJ466wZwLrh+FZiniq/4jxnV2cchVxvwffQ1Nsjd5pqEN4tRpSvl+mRdzEHPaXX/XysW3Ay9gQ==, tarball: file:projects/document.tgz}
name: '@rush-temp/document'
version: 0.0.0
dependencies:
'@rushstack/heft': 0.47.11
'@types/heft-jest': 1.0.3
'@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464
'@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4
eslint: 8.27.0
eslint-config-standard-with-typescript: 23.0.0_c9fe9619f50f4e82337a86c3af25e566
eslint-plugin-import: 2.26.0_eslint@8.27.0
eslint-plugin-n: 15.5.1_eslint@8.27.0
eslint-plugin-promise: 6.1.1_eslint@8.27.0
prettier: 2.8.8
typescript: 4.8.4
transitivePeerDependencies:
- supports-color
dev: false
file:projects/elastic.tgz_@types+node@16.11.68:
resolution: {integrity: sha512-PY7mQyOCUoEgFlhhSs3lYKHUBwIHNsNOQzOgojlTo+YreJOUeTQFo8/1nqlva6uq5B0+l85QUiqiV3YYHOytOQ==, tarball: file:projects/elastic.tgz}
id: file:projects/elastic.tgz
@@ -18840,7 +18749,7 @@ packages:
dev: false
file:projects/model-all.tgz_typescript@4.8.4:
resolution: {integrity: sha512-g6cNmmiQ8u2RKGeoHFUfJZpwv3ANw9G+eL5w9ugE1641qM35z4Mc98pCVvC4qo7KxEUkf71fEAkVn1PYEhd1Zw==, tarball: file:projects/model-all.tgz}
resolution: {integrity: sha512-4l1yEr88a5e6IOcEXjJn6RdM26DoIb8wwpdwk4a0UBk0fbp8O/kmo7+jKGmf0kFL+ibLgKNvFm5BYVpue+hA1g==, tarball: file:projects/model-all.tgz}
id: file:projects/model-all.tgz
name: '@rush-temp/model-all'
version: 0.0.0
@@ -19034,27 +18943,6 @@ packages:
- typescript
dev: false
file:projects/model-document.tgz_typescript@4.8.4:
resolution: {integrity: sha512-0+DwgNfG3I1w8ZwQYeq7y8oTHniKJuvXKruBT4PM89y2bXZ+PcdL/DS2iHzfIQ2DtOatbIHd33mR7kgR1JZwCQ==, tarball: file:projects/model-document.tgz}
id: file:projects/model-document.tgz
name: '@rush-temp/model-document'
version: 0.0.0
dependencies:
'@rushstack/heft': 0.47.11
'@types/heft-jest': 1.0.3
'@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464
'@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4
eslint: 8.27.0
eslint-config-standard-with-typescript: 23.0.0_c9fe9619f50f4e82337a86c3af25e566
eslint-plugin-import: 2.26.0_eslint@8.27.0
eslint-plugin-n: 15.5.1_eslint@8.27.0
eslint-plugin-promise: 6.1.1_eslint@8.27.0
prettier: 2.8.8
transitivePeerDependencies:
- supports-color
- typescript
dev: false
file:projects/model-gmail.tgz_typescript@4.8.4:
resolution: {integrity: sha512-x0wXbISbTDWAxhxqfojSV2B8FrPzRDM9kZcVqC7fxRObWIFzJKvqBn4FRVk3mMhFdKBMtzdg+SBbJIhm9gDDCg==, tarball: file:projects/model-gmail.tgz}
id: file:projects/model-gmail.tgz
@@ -20209,41 +20097,6 @@ packages:
- supports-color
dev: false
file:projects/pod-collaborator.tgz_bufferutil@4.0.7:
resolution: {integrity: sha512-1/aln2xUZfGeRUlzGkjmMklZF/d4eaiAleHSuT8Z5SE7+AlI3sUoIZU9Pqfm/xtX2pI5zAQzduQtMfjNyiV5YA==, tarball: file:projects/pod-collaborator.tgz}
id: file:projects/pod-collaborator.tgz
name: '@rush-temp/pod-collaborator'
version: 0.0.0
dependencies:
'@rushstack/heft': 0.47.11
'@types/heft-jest': 1.0.3
'@types/node': 16.11.68
'@types/ws': 8.5.3
'@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464
'@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4
cross-env: 7.0.3
esbuild: 0.16.14
eslint: 8.27.0
eslint-config-standard-with-typescript: 23.0.0_c9fe9619f50f4e82337a86c3af25e566
eslint-plugin-import: 2.26.0_eslint@8.27.0
eslint-plugin-n: 15.5.1_eslint@8.27.0
eslint-plugin-promise: 6.1.1_eslint@8.27.0
lib0: 0.2.73
lodash.debounce: 4.0.8
prettier: 2.8.8
ts-node: 10.9.1_867af3484524ae72fe2b1aa24b40f5ee
typescript: 4.8.4
ws: 8.11.0_bufferutil@4.0.7
y-protocols: 1.0.5
yjs: 13.5.52
transitivePeerDependencies:
- '@swc/core'
- '@swc/wasm'
- bufferutil
- supports-color
- utf-8-validate
dev: false
file:projects/pod-front.tgz:
resolution: {integrity: sha512-7RjucQVYaMbYBJEUo6gC6sAepQUPSxoErDAM22zx68541Ds2Jx6FmD/kHEDJSqk5ve1ECKPTL2xmMuStWiTn7A==, tarball: file:projects/pod-front.tgz}
name: '@rush-temp/pod-front'
@@ -20287,7 +20140,7 @@ packages:
dev: false
file:projects/pod-server.tgz:
resolution: {integrity: sha512-SWB1f4OdOIZosUoV511VmwfS+cawaMdX+W/PdpsAOHHRG17St/PLy4+IpVec0B3xeFLXq9pdXiBXq5J73LwWKA==, tarball: file:projects/pod-server.tgz}
resolution: {integrity: sha512-0g+8yGEuBrExc15sVQk2hZKTF1KVrcU6VVtUU8GdUxBN07HJb9l8luuYXsbHMwW+FU/e7FKiVK9VJh2FVmzuSw==, tarball: file:projects/pod-server.tgz}
name: '@rush-temp/pod-server'
version: 0.0.0
dependencies:
@@ -20395,7 +20248,7 @@ packages:
dev: false
file:projects/prod.tgz_91152849c259b1b3925f7bb3d415bc80:
resolution: {integrity: sha512-wZWIAN+CPlPommWoqqH2yf11giIQ+B7Gbx6NQ8hkQ3PeZS2zJWsN3Ki+4vYu+BOZHwthzEJn3Y9LhKsyTL9m2A==, tarball: file:projects/prod.tgz}
resolution: {integrity: sha512-crJHAbNcTU2tnkH30njWj7LLUQbPQXdgDc6tGxZESKmARWrC2GxJ3PIIryN1iK3vO21qE7vBPO6oDoXpIOUjSQ==, tarball: file:projects/prod.tgz}
id: file:projects/prod.tgz
name: '@rush-temp/prod'
version: 0.0.0
@@ -22087,7 +21940,7 @@ packages:
- supports-color
dev: false
file:projects/text-editor.tgz_1e646fd62a3adc9d0b41f256dafe3d38:
file:projects/text-editor.tgz_a1d864769aaf53d09b76fe134ab55e60:
resolution: {integrity: sha512-mZ+9T1R2k5X+qEj4fXliwEVDzmBbGEggRReeFSTver56sVbuZQrbnAeeHEa1kMX6rD/O5kKTn8Bwk+S97y3jkw==, tarball: file:projects/text-editor.tgz}
id: file:projects/text-editor.tgz
name: '@rush-temp/text-editor'
@@ -22121,7 +21974,6 @@ packages:
'@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464
'@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4
diff: 5.1.0
emoji-regex: 10.2.1
eslint: 8.27.0
eslint-config-standard-with-typescript: 23.0.0_c9fe9619f50f4e82337a86c3af25e566
eslint-plugin-import: 2.26.0_eslint@8.27.0
@@ -22149,7 +22001,7 @@ packages:
svelte-loader: 3.1.4_svelte@3.55.1
svelte-preprocess: 5.0.3_6420a3eba9d5580d9c2f627c17e61722
typescript: 4.8.4
y-prosemirror: 1.2.1_4b437ae61db91263defb65d2247376eb
y-prosemirror: 1.2.1_709ebdfd1c5bc23c335c8dea11286d09
y-websocket: 1.5.0_yjs@13.5.52
yjs: 13.5.52
transitivePeerDependencies:
-14
View File
@@ -63,19 +63,6 @@ services:
- INIT_WORKSPACE=demo-tracker
- MODEL_ENABLED=*
restart: unless-stopped
collaborator:
image: hardcoreeng/collaborator
links:
- transactor
ports:
- 3078:3078
environment:
- COLLABORATOR_PORT=3078
- SECRET=secret
- MINIO_ENDPOINT=minio
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
restart: unless-stopped
front:
image: hardcoreeng/front
links:
@@ -90,7 +77,6 @@ services:
- SERVER_SECRET=secret
- ACCOUNTS_URL=http://localhost:3000
- REKONI_URL=http://localhost:4004
- COLLABORATOR_URL=ws://localhost:3078
- CALENDAR_URL=http://localhost:8095
- GMAIL_URL=http://localhost:8088
- TELEGRAM_URL=http://localhost:8086
-2
View File
@@ -7,5 +7,3 @@ CALENDAR_URL=http://localhost:8095
FRONT_URL=http://localhost:8080
REKONI_URL=http://localhost:4004
COLLABORATOR_URL=ws://locahost:3078
-1
View File
@@ -1,6 +1,5 @@
{
"ACCOUNTS_URL":"http://localhost:3000",
"COLLABORATOR_URL": "ws://localhost:3078",
"UPLOAD_URL":"/files",
"REKONI_URL": "http://localhost:4004"
}
-3
View File
@@ -158,9 +158,6 @@
"@hcengineering/hr-resources": "^0.6.0",
"@hcengineering/server-hr": "^0.6.0",
"@hcengineering/server-hr-resources": "^0.6.0",
"@hcengineering/document": "^0.6.0",
"@hcengineering/document-assets": "^0.6.0",
"@hcengineering/document-resources": "^0.6.0",
"@hcengineering/bitrix": "^0.6.41",
"@hcengineering/bitrix-assets": "^0.6.0",
"@hcengineering/bitrix-resources": "^0.6.0",
-1
View File
@@ -1,6 +1,5 @@
{
"ACCOUNTS_URL":"https://account.hc.engineering",
"COLLABORATOR_URL": "wss://collaborator.hc.engineering",
"UPLOAD_URL":"/files",
"MODEL_VERSION": null,
"TELEGRAM_URL": "https://telegram.hc.engineering",
-1
View File
@@ -1,6 +1,5 @@
{
"ACCOUNTS_URL":"/account",
"COLLABORATOR_URL": "ws://localhost:3078",
"UPLOAD_URL":"/files",
"MODEL_VERSION": null,
"TELEGRAM_URL": "http://localhost:8086",
-6
View File
@@ -23,7 +23,6 @@ import calendar, { calendarId } from '@hcengineering/calendar'
import { chunterId } from '@hcengineering/chunter'
import client, { clientId } from '@hcengineering/client'
import { contactId } from '@hcengineering/contact'
import document, { documentId } from '@hcengineering/document'
import gmail, { gmailId } from '@hcengineering/gmail'
import { hrId } from '@hcengineering/hr'
import { imageCropperId } from '@hcengineering/image-cropper'
@@ -55,7 +54,6 @@ import '@hcengineering/board-assets'
import '@hcengineering/calendar-assets'
import '@hcengineering/chunter-assets'
import '@hcengineering/contact-assets'
import '@hcengineering/document-assets'
import '@hcengineering/gmail-assets'
import '@hcengineering/hr-assets'
import '@hcengineering/inventory-assets'
@@ -86,7 +84,6 @@ interface Config {
ACCOUNTS_URL: string
UPLOAD_URL: string
MODEL_VERSION: string
COLLABORATOR_URL: string
REKONI_URL: string
TELEGRAM_URL: string
GMAIL_URL: string
@@ -104,8 +101,6 @@ export async function configurePlatform() {
setMetadata(login.metadata.AccountsUrl, config.ACCOUNTS_URL)
setMetadata(presentation.metadata.UploadURL, config.UPLOAD_URL)
setMetadata(document.metadata.CollaboratorUrl, config.COLLABORATOR_URL)
if (config.MODEL_VERSION != null) {
console.log('Minimal Model version requirement', config.MODEL_VERSION)
setMetadata(presentation.metadata.RequiredVersion, config.MODEL_VERSION)
@@ -160,7 +155,6 @@ export async function configurePlatform() {
addLocation(boardId, () => import(/* webpackChunkName: "board" */ '@hcengineering/board-resources'))
addLocation(automationId, () => import(/* webpackChunkName: "automation" */ '@hcengineering/automation-resources'))
addLocation(hrId, () => import(/* webpackChunkName: "hr" */ '@hcengineering/hr-resources'))
addLocation(documentId, () => import(/* webpackChunkName: "document" */ '@hcengineering/document-resources'))
addLocation(bitrixId, () => import(/* webpackChunkName: "bitrix" */ '@hcengineering/bitrix-resources'))
addLocation(requestId, () => import(/* webpackChunkName: "request" */ '@hcengineering/request-resources'))
addLocation(supportId, () => import(/* webpackChunkName: "support" */ '@hcengineering/support-resources'))
-1
View File
@@ -74,7 +74,6 @@
"@hcengineering/model-preference": "^0.6.0",
"@hcengineering/model-hr": "^0.6.0",
"@hcengineering/model-server-hr": "^0.6.0",
"@hcengineering/model-document": "^0.6.0",
"@hcengineering/model-bitrix": "^0.6.0",
"@hcengineering/model-request": "^0.6.0",
"@hcengineering/model-server-request": "^0.6.0",
-13
View File
@@ -26,7 +26,6 @@ import calendar, { calendarId, createModel as calendarModel } from '@hcengineeri
import chunter, { chunterId, createModel as chunterModel } from '@hcengineering/model-chunter'
import contact, { contactId, createModel as contactModel } from '@hcengineering/model-contact'
import { createModel as coreModel } from '@hcengineering/model-core'
import document, { documentId, createModel as documentModel } from '@hcengineering/model-document'
import gmail, { gmailId, createModel as gmailModel } from '@hcengineering/model-gmail'
import hr, { hrId, createModel as hrModel } from '@hcengineering/model-hr'
import inventory, { inventoryId, createModel as inventoryModel } from '@hcengineering/model-inventory'
@@ -214,18 +213,6 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[
classFilter: defaultFilter
}
],
[
documentModel,
documentId,
{
label: document.string.ConfigLabel,
description: document.string.ConfigDescription,
enabled: false,
beta: true,
icon: document.icon.DocumentApplication,
classFilter: defaultFilter
}
],
[
trackerModel,
trackerId,
-2
View File
@@ -35,7 +35,6 @@ import { viewOperation } from '@hcengineering/model-view'
import { trackerOperation } from '@hcengineering/model-tracker'
import { boardOperation } from '@hcengineering/model-board'
import { hrOperation } from '@hcengineering/model-hr'
import { documentOperation } from '@hcengineering/model-document'
import { bitrixOperation } from '@hcengineering/model-bitrix'
import { calendarOperation } from '@hcengineering/model-calendar'
@@ -60,7 +59,6 @@ export const migrateOperations: [string, MigrateOperation][] = [
['tracker', trackerOperation],
['board', boardOperation],
['hr', hrOperation],
['document', documentOperation],
['bitrix', bitrixOperation],
['inventiry', inventoryOperation]
]
-7
View File
@@ -1,7 +0,0 @@
module.exports = {
extends: ['./node_modules/@hcengineering/model-rig/profiles/default/config/eslint.config.json'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
}
}
-4
View File
@@ -1,4 +0,0 @@
*
!/lib/**
!CHANGELOG.md
/lib/**/__tests__/
-18
View File
@@ -1,18 +0,0 @@
// The "rig.json" file directs tools to look for their config files in an external package.
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
/**
* (Required) The name of the rig package to inherit from.
* It should be an NPM package name with the "-rig" suffix.
*/
"rigPackageName": "@hcengineering/model-rig"
/**
* (Optional) Selects a config profile from the rig package. The name must consist of
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
* If omitted, then the "default" profile will be used."
*/
// "rigProfile": "your-profile-name"
}
-46
View File
@@ -1,46 +0,0 @@
{
"name": "@hcengineering/model-document",
"version": "0.6.0",
"main": "lib/index.js",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "heft build",
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"lint": "eslint src",
"format": "prettier --write src && eslint --fix src"
},
"devDependencies": {
"@hcengineering/model-rig": "^0.6.0",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-n": "^15.4.0",
"eslint": "^8.26.0",
"@types/heft-jest": "^1.0.3",
"@typescript-eslint/parser": "^5.41.0",
"eslint-config-standard-with-typescript": "^23.0.0",
"prettier": "^2.7.1",
"@rushstack/heft": "^0.47.9"
},
"dependencies": {
"@hcengineering/model-core": "^0.6.0",
"@hcengineering/model-chunter": "^0.6.0",
"@hcengineering/model-workbench": "^0.6.1",
"@hcengineering/model-attachment": "^0.6.0",
"@hcengineering/model-view": "^0.6.0",
"@hcengineering/model-presentation": "^0.6.0",
"@hcengineering/model": "^0.6.6",
"@hcengineering/setting": "^0.6.9",
"@hcengineering/core": "^0.6.27",
"@hcengineering/ui": "^0.6.10",
"@hcengineering/platform": "^0.6.9",
"@hcengineering/notification": "^0.6.14",
"@hcengineering/document": "^0.6.0",
"@hcengineering/document-resources": "^0.6.0",
"@hcengineering/view": "^0.6.8",
"@hcengineering/contact": "^0.6.19",
"@hcengineering/tags": "^0.6.11"
}
}
-269
View File
@@ -1,269 +0,0 @@
//
// Copyright © 2022 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 contact, { Employee } from '@hcengineering/contact'
import type { Domain, Markup, Ref } from '@hcengineering/core'
import { IndexKind } from '@hcengineering/core'
import {
CollaboratorDocument,
Document,
DocumentRequest,
DocumentRequestKind,
DocumentVersion,
DocumentVersionState,
documentId
} from '@hcengineering/document'
import {
ArrOf,
Builder,
Collection,
Hidden,
Index,
Model,
Prop,
ReadOnly,
TypeNumber,
TypeRef,
TypeString,
UX
} from '@hcengineering/model'
import attachment, { TAttachment } from '@hcengineering/model-attachment'
import chunter from '@hcengineering/model-chunter'
import core, { TAttachedDoc, TDoc } from '@hcengineering/model-core'
import presentation from '@hcengineering/model-presentation'
import view, { actionTemplates, createAction } from '@hcengineering/model-view'
import workbench from '@hcengineering/model-workbench'
import tags from '@hcengineering/tags'
import document from './plugin'
export { documentId } from '@hcengineering/document'
export { documentOperation } from './migration'
export { document as default }
export const DOMAIN_DOCUMENT = 'document' as Domain
@Model(document.class.DocumentRequest, core.class.AttachedDoc, DOMAIN_DOCUMENT)
@UX(document.string.Document)
export class TDocumentRequest extends TAttachedDoc implements DocumentRequest {
kind!: DocumentRequestKind
assignee!: Ref<Employee>
message!: Markup
}
@Model(document.class.CollaboratorDocument, attachment.class.Attachment, DOMAIN_DOCUMENT)
@UX(document.string.Document)
export class TCollaboratorDocument extends TAttachment implements CollaboratorDocument {}
@Model(document.class.DocumentVersion, core.class.AttachedDoc, DOMAIN_DOCUMENT)
@UX(document.string.Version)
export class TDocumentVersion extends TAttachedDoc implements DocumentVersion {
@Prop(TypeNumber(), document.string.Version)
@Index(IndexKind.FullText)
@ReadOnly()
version!: number
@Prop(TypeString(), document.string.Description)
@Index(IndexKind.FullText)
description!: Markup
@Prop(TypeString(), document.string.Description)
@Index(IndexKind.FullText)
reason!: Markup
@Prop(TypeString(), document.string.Description)
@Index(IndexKind.FullText)
impact!: Markup
// @Prop(TypeString(), document.string.Status)
state!: DocumentVersionState
@Prop(TypeString(), document.string.Document)
@Hidden()
content!: Markup
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files })
attachments!: number
@Prop(Collection(chunter.class.Comment), chunter.string.Comments)
comments!: number
contentAttachmentId!: Ref<CollaboratorDocument>
initialContentId!: Ref<CollaboratorDocument>
}
@Model(document.class.Document, core.class.Doc, DOMAIN_DOCUMENT)
@UX(document.string.Document, document.icon.Document, undefined, 'name')
export class TDocument extends TDoc implements Document {
@Prop(TypeString(), document.string.Name)
@Index(IndexKind.FullText)
name!: string
@Prop(TypeNumber(), document.string.Version)
@ReadOnly()
@Hidden()
version!: number
@Prop(TypeNumber(), document.string.LastRevision)
@ReadOnly()
@Hidden()
latest!: number
@Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files })
attachments?: number
@Prop(Collection(chunter.class.Comment), chunter.string.Comments)
comments?: number
@Prop(Collection(tags.class.TagReference), document.string.Labels)
labels?: number
@Prop(Collection(document.class.DocumentVersion), document.string.Version)
@Hidden()
versions!: number
@Prop(ArrOf(TypeRef(contact.mixin.Employee)), document.string.Authors)
authors!: Ref<Employee>[]
@Prop(ArrOf(TypeRef(contact.mixin.Employee)), document.string.Reviewers)
reviewers!: Ref<Employee>[]
@Prop(ArrOf(TypeRef(contact.mixin.Employee)), document.string.Approvers)
approvers!: Ref<Employee>[]
@Prop(Collection(document.class.DocumentRequest), document.string.Requests)
@Hidden()
requests!: number
}
export function createModel (builder: Builder): void {
builder.createModel(TDocument, TDocumentVersion, TCollaboratorDocument, TDocumentRequest)
builder.createDoc(
workbench.class.Application,
core.space.Model,
{
label: document.string.DocumentApplication,
icon: document.icon.DocumentApplication,
alias: documentId,
hidden: false,
navigatorModel: {
specials: [
{
id: 'my-documents',
position: 'top',
label: document.string.MyDocuments,
icon: document.icon.Document,
component: document.component.MyDocuments
},
{
id: 'library',
position: 'top',
label: document.string.Library,
icon: document.icon.Library,
component: document.component.Documents
}
],
spaces: []
},
navHeaderComponent: document.component.NewDocumentHeader
},
document.app.Documents
)
builder.mixin(document.class.Document, core.class.Class, view.mixin.ObjectFactory, {
component: document.component.CreateDocument
})
builder.mixin(document.class.Document, core.class.Class, view.mixin.ObjectPanel, {
component: document.component.EditDoc
})
builder.createDoc(
view.class.Viewlet,
core.space.Model,
{
attachTo: document.class.Document,
descriptor: view.viewlet.Table,
config: [
'',
{
key: '',
presenter: document.component.Version,
label: document.string.Version
},
'comments',
'attachments',
{
key: '',
presenter: tags.component.TagsPresenter,
label: document.string.Labels,
sortingKey: 'labels',
props: {
_class: document.class.Document,
key: 'labels',
icon: document.icon.Document
}
},
'modifiedOn'
],
options: {
lookup: {
_id: {
versions: document.class.DocumentVersion
}
}
}
},
document.viewlet.TableDocument
)
builder.mixin(document.class.Document, core.class.Class, view.mixin.ObjectEditor, {
editor: document.component.EditDoc
})
builder.mixin(document.class.Document, core.class.Class, view.mixin.ObjectPresenter, {
presenter: document.component.DocumentPresenter
})
builder.mixin(document.class.DocumentVersion, core.class.Class, view.mixin.ObjectPresenter, {
presenter: document.component.DocumentVersionPresenter
})
builder.createDoc(
presentation.class.ObjectSearchCategory,
core.space.Model,
{
icon: document.icon.Document,
label: document.string.SearchDocument,
query: document.completion.DocumentQuery
},
document.completion.DocumentQueryCategory
)
createAction(builder, {
...actionTemplates.open,
actionProps: {
component: document.component.EditDoc
},
target: document.class.Document,
context: {
mode: ['browser', 'context'],
group: 'create'
},
override: [view.action.Open]
})
builder.mixin(document.class.DocumentVersion, core.class.Class, view.mixin.CollectionEditor, {
editor: document.component.DocumentVersions
})
}
-62
View File
@@ -1,62 +0,0 @@
//
// Copyright © 2022 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 { TxOperations } from '@hcengineering/core'
import { createOrUpdate, MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model'
import core from '@hcengineering/model-core'
import tags from '@hcengineering/tags'
import document from './index'
async function createSpace (tx: TxOperations): Promise<void> {
const contacts = await tx.findOne(core.class.Space, {
_id: document.space.Documents
})
if (contacts === undefined) {
await tx.createDoc(
core.class.Space,
core.space.Space,
{
name: 'Documents',
description: 'Documents',
private: false,
archived: false,
members: []
},
document.space.Documents
)
}
}
export const documentOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createSpace(tx)
await createOrUpdate(
tx,
tags.class.TagCategory,
tags.space.Tags,
{
icon: tags.icon.Tags,
label: 'Labels',
targetClass: document.class.Document,
tags: [],
default: true
},
document.category.Other
)
}
}
-48
View File
@@ -1,48 +0,0 @@
//
// Copyright © 2022 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 { Doc, Ref } from '@hcengineering/core'
import {} from '@hcengineering/core'
import { documentId } from '@hcengineering/document'
import document from '@hcengineering/document-resources/src/plugin'
import { ObjectSearchCategory, ObjectSearchFactory } from '@hcengineering/model-presentation'
import { IntlString, mergeIds, Resource } from '@hcengineering/platform'
import { TagCategory } from '@hcengineering/tags'
import { AnyComponent } from '@hcengineering/ui'
import { ActionCategory } from '@hcengineering/view'
export default mergeIds(documentId, document, {
component: {
Documents: '' as AnyComponent,
DocumentPresenter: '' as AnyComponent,
DocumentVersionPresenter: '' as AnyComponent,
DocumentVersions: '' as AnyComponent
},
completion: {
DocumentQuery: '' as Resource<ObjectSearchFactory>,
DocumentQueryCategory: '' as Ref<ObjectSearchCategory>
},
category: {
Document: '' as Ref<ActionCategory>,
Other: '' as Ref<TagCategory>
},
viewlet: {
TableDocument: '' as Ref<Doc>
},
string: {
ConfigLabel: '' as IntlString,
ConfigDescription: '' as IntlString
}
})
-8
View File
@@ -1,8 +0,0 @@
{
"extends": "./node_modules/@hcengineering/model-rig/profiles/default/tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib",
}
}
-7
View File
@@ -1,7 +0,0 @@
module.exports = {
extends: ['./node_modules/@hcengineering/platform-rig/profiles/assets/config/eslint.config.json'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
}
}
-20
View File
@@ -1,20 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="documentapplication" viewBox="0 0 32 32">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 4C8.89543 4 8 4.89543 8 6V26C8 27.1046 8.89543 28 10 28H22C23.1046 28 24 27.1046 24 26V12H20C17.7909 12 16 10.2091 16 8V4H10ZM18 4.41421V8C18 9.10457 18.8954 10 20 10H23.5858L18 4.41421ZM6 6C6 3.79086 7.79086 2 10 2H17.5858C18.1162 2 18.6249 2.21071 19 2.58579L25.4142 9C25.7893 9.37507 26 9.88378 26 10.4142V26C26 28.2091 24.2091 30 22 30H10C7.79086 30 6 28.2091 6 26V6ZM10 17C10 16.4477 10.4477 16 11 16H15C15.5523 16 16 16.4477 16 17C16 17.5523 15.5523 18 15 18H11C10.4477 18 10 17.5523 10 17ZM10 21C10 20.4477 10.4477 20 11 20H21C21.5523 20 22 20.4477 22 21C22 21.5523 21.5523 22 21 22H11C10.4477 22 10 21.5523 10 21Z" />
</symbol>
<symbol id="newdocument" viewBox="0 0 16 16">
<path d="M14.7826 3.26359C15.1313 2.69123 15.0606 1.93115 14.5705 1.43492C14.0757 0.933932 13.3153 0.865765 12.7483 1.23041C13.2123 2.09277 13.9198 2.79999 14.7826 3.26359Z"/>
<path d="M11.8171 2.11829L6.78472 7.18C7.77457 7.47517 8.57699 8.21908 8.95006 9.18198L13.9064 4.20208C13.0535 3.68436 12.3369 2.9696 11.8171 2.11829Z"/>
<path d="M7.91486 10.1761C7.80538 9.1186 6.91913 8.30487 5.8592 8.29183C5.53827 8.92804 5.21105 9.90848 5.01729 10.5311C4.93355 10.8002 5.16675 11.0527 5.44262 10.9905C6.16831 10.8268 7.36057 10.5217 7.91486 10.1761Z"/>
<path d="M4.75 2C2.67893 2 1 3.67893 1 5.75V11.25C1 13.3211 2.67893 15 4.75 15H10.2501C12.3212 15 14.0001 13.3211 14.0001 11.25V8C14.0001 7.58579 13.6643 7.25 13.2501 7.25C12.8359 7.25 12.5001 7.58579 12.5001 8V11.25C12.5001 12.4926 11.4927 13.5 10.2501 13.5H4.75C3.50736 13.5 2.5 12.4926 2.5 11.25V5.75C2.5 4.50736 3.50736 3.5 4.75 3.5H7C7.41421 3.5 7.75 3.16421 7.75 2.75C7.75 2.33579 7.41421 2 7 2H4.75Z"/>
</symbol>
<symbol id="document" viewBox="0 0 32 32">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 4C8.89543 4 8 4.89543 8 6V26C8 27.1046 8.89543 28 10 28H22C23.1046 28 24 27.1046 24 26V12H20C17.7909 12 16 10.2091 16 8V4H10ZM18 4.41421V8C18 9.10457 18.8954 10 20 10H23.5858L18 4.41421ZM6 6C6 3.79086 7.79086 2 10 2H17.5858C18.1162 2 18.6249 2.21071 19 2.58579L25.4142 9C25.7893 9.37507 26 9.88378 26 10.4142V26C26 28.2091 24.2091 30 22 30H10C7.79086 30 6 28.2091 6 26V6ZM10 17C10 16.4477 10.4477 16 11 16H15C15.5523 16 16 16.4477 16 17C16 17.5523 15.5523 18 15 18H11C10.4477 18 10 17.5523 10 17ZM10 21C10 20.4477 10.4477 20 11 20H21C21.5523 20 22 20.4477 22 21C22 21.5523 21.5523 22 21 22H11C10.4477 22 10 21.5523 10 21Z" />
</symbol>
<symbol id="library" viewBox="0 0 24 24">
<path d="M21,2.2h-5h-5c-0.4,0-0.8,0.3-0.8,0.8v18c0,0.4,0.3,0.8,0.8,0.8h5h5c0.4,0,0.8-0.3,0.8-0.8V3C21.8,2.6,21.4,2.2,21,2.2z M11.8,3.8h3.5v16.5h-3.5V3.8z M20.2,20.2h-3.5V3.8h3.5V20.2z"/>
<path d="M9.1,2.8l-4-0.5c-0.2,0-0.4,0-0.6,0.2S4.3,2.7,4.3,2.9l-2,17.5c0,0.4,0.2,0.8,0.7,0.8l4.2,0.5c0.2,0,0.4,0,0.6-0.2C7.9,21.5,8,21.3,8,21.1L9.7,3.6C9.8,3.2,9.5,2.8,9.1,2.8z M6.6,20.2l-2.7-0.3l1.8-16l2.5,0.3L6.6,20.2z"/>
<path d="M18.5,9.8c0.4,0,0.8-0.3,0.8-0.8V7.5c0-0.4-0.3-0.8-0.8-0.8s-0.8,0.3-0.8,0.8V9C17.8,9.4,18.1,9.8,18.5,9.8z"/>
<path d="M13.5,6.8c-0.4,0-0.8,0.3-0.8,0.8V9c0,0.4,0.3,0.8,0.8,0.8s0.8-0.3,0.8-0.8V7.5C14.2,7.1,13.9,6.8,13.5,6.8z"/>
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

-5
View File
@@ -1,5 +0,0 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
"rigPackageName": "@hcengineering/platform-rig",
"rigProfile": "assets"
}
-56
View File
@@ -1,56 +0,0 @@
{
"string": {
"CreateDocument": "Create an document",
"DocumentCreateLabel": "Document",
"Documents": "Documents",
"CreateAnVersion": "Create new version",
"Document": "Document",
"DocumentNamePlaceholder": "Name...",
"Name": "Name",
"Cancel": "Cancel",
"EditorPlaceholder": "type to start editing...",
"Version": "Version",
"SearchDocument": "Search document...",
"Revision": "Revision",
"NoVersions": "No version's defined",
"CreateEnVersion": "Create version for review",
"Versions": "Versions",
"CreateDocumentVersion": "Create new version",
"Approvers": "Approvers",
"Status": "Status",
"LastRevision": "Last revision",
"DocumentApplication": "Documents",
"MyDocuments": "My documents",
"Library": "Library",
"Labels": "Labels",
"AddLabel": "Add label...",
"Authors": "Authors",
"DocumentVersionPlaceholder": "version...",
"DescriptionPlaceholder": "type for details...",
"PendingReview": "Pending",
"Latest": "Actual",
"Draft": "Draft",
"Description": "Description",
"Reviewers": "Reviewers",
"ViewMode": "View",
"EditMode": "Edit",
"SuggestMode": "Suggest",
"CreateDraft": "New Draft",
"SendForApproval": "Ask Approval",
"SendForReview": "Ask for Review",
"Approve": "Approve",
"Reject": "Reject",
"Approved": "Approved",
"Rejected": "Rejected",
"CompareTo": "Compare to...",
"ConfigLabel": "Documents",
"ConfigDescription": "Extension for collaborative document editing"
}
}
-55
View File
@@ -1,55 +0,0 @@
{
"string": {
"CreateDocument": "Создать документ",
"DocumentCreateLabel": "Документ",
"Documents": "Документы",
"CreateAnVersion": "Создать новую версию",
"Document": "Документ",
"DocumentNamePlaceholder": "Имя...",
"Name": "Имя",
"Cancel": "Отмена",
"EditorPlaceholder": "введите для начала...",
"Version": "Версия",
"SearchDocument": "Найти документ...",
"Revision": "Ревизия",
"NoVersions": "Версии не определены",
"CreateEnVersion": "Создать версию для оценки",
"Versions": "Версии",
"CreateDocumentVersion": "Создать версию",
"Approvers": "Утверждающие",
"Status": "Статус",
"LastRevision": "Последняя ревизия",
"DocumentApplication": "Документы",
"MyDocuments": "Мои документы",
"Library": "Библиотека",
"Labels": "Метки",
"AddLabel": "Добавить метку...",
"Authors": "Авторы",
"DocumentVersionPlaceholder": "версия...",
"DescriptionPlaceholder": "введите для деталей...",
"PendingReview": "Ожидает",
"Latest": "Актуально",
"Draft": "Рабочая копия",
"Description": "Описание",
"Reviewers": "Рецензенты",
"ViewMode": "Просмотр",
"EditMode": "Редактирование",
"SuggestMode": "Комментирование",
"CreateDraft": "Новая рабочая копия",
"SendForApproval": "Попросить утверждения",
"SendForReview": "Попросить рецензию",
"Approve": "Утвердить",
"Reject": "Отказать",
"Approved": "Утверждено",
"Rejected": "Отказано",
"CompareTo": "Сравнить с...",
"ConfigLabel": "Документы",
"ConfigDescription": "Расширение по работе с текстовыми документами"
}
}
-35
View File
@@ -1,35 +0,0 @@
{
"name": "@hcengineering/document-assets",
"version": "0.6.0",
"main": "lib/index.js",
"author": "Anticrm Platform Contributors",
"template": "@hcengineering/assets-package",
"license": "EPL-2.0",
"scripts": {
"build": "heft build",
"test": "heft test",
"build:docs": "",
"lint": "eslint src",
"lint:fix": "eslint --fix src",
"format": "prettier --write src && eslint --fix src",
"build:watch": "tsc"
},
"devDependencies": {
"@hcengineering/platform-rig": "^0.6.0",
"@types/heft-jest": "^1.0.3",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"@typescript-eslint/parser": "^5.41.0",
"eslint-config-standard-with-typescript": "^23.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.4.0",
"eslint-plugin-promise": "^6.1.1",
"eslint": "^8.26.0",
"prettier": "^2.7.1",
"@rushstack/heft": "^0.47.9",
"@types/node": "~16.11.12"
},
"dependencies": {
"@hcengineering/platform": "^0.6.9",
"@hcengineering/document": "^0.6.0"
}
}
@@ -1,6 +0,0 @@
import { makeLocalesTest } from '@hcengineering/platform'
it(
'Locales are equale',
makeLocalesTest((lang) => import(`../../lang/${lang}.json`))
)
-26
View File
@@ -1,26 +0,0 @@
//
// Copyright © 2022 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 document, { documentId } from '@hcengineering/document'
import { addStringsLoader, loadMetadata } from '@hcengineering/platform'
const icons = require('../assets/icons.svg') as string // eslint-disable-line
loadMetadata(document.icon, {
DocumentApplication: `${icons}#documentapplication`,
NewDocument: `${icons}#newdocument`,
Document: `${icons}#document`,
Library: `${icons}#library`
})
addStringsLoader(documentId, async (lang: string) => await import(`../lang/${lang}.json`))
-18
View File
@@ -1,18 +0,0 @@
{
"compilerOptions": {
"moduleResolution": "node",
"target": "esnext",
"module": "commonjs",
"sourceMap": true,
"types": ["node", "heft-jest"],
"declaration": true,
"outDir": "./lib",
"strict": true,
"skipLibCheck": true,
"esModuleInterop": true,
"lib": [
"esnext",
"dom"
]
}
}
-7
View File
@@ -1,7 +0,0 @@
module.exports = {
extends: ['./node_modules/@hcengineering/platform-rig/profiles/ui/config/eslint.config.json'],
parserOptions: { tsconfigRootDir: __dirname },
settings: {
'svelte3/ignore-styles': () => true
}
}
@@ -1,5 +0,0 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
"rigPackageName": "@hcengineering/platform-rig",
"rigProfile": "ui"
}
-54
View File
@@ -1,54 +0,0 @@
{
"name": "@hcengineering/document-resources",
"version": "0.6.0",
"main": "src/index.ts",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "tsc --incremental --noEmit --outDir ./dist_cache && echo build",
"build:docs": "api-extractor run --local",
"lint": "svelte-check && eslint",
"lint:fix": "eslint --fix src",
"format": "prettier --write --plugin-search-dir=. src && eslint --fix src",
"svelte-check": "svelte-check --output human",
"build:watch": "tsc --incremental --noEmit --outDir ./dist_cache"
},
"devDependencies": {
"svelte-loader": "^3.1.3",
"sass": "^1.53.0",
"svelte-preprocess": "5.0.3",
"@hcengineering/platform-rig": "^0.6.0",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"@typescript-eslint/parser": "^5.41.0",
"eslint-config-standard-with-typescript": "^23.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.4.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-svelte3": "^4.0.0",
"prettier-plugin-svelte": "^2.8.0",
"eslint": "^8.26.0",
"prettier": "^2.7.1",
"svelte-check": "3.2.0",
"typescript": "^4.3.5"
},
"dependencies": {
"@hcengineering/platform": "^0.6.9",
"svelte": "3.55.1",
"@hcengineering/document": "^0.6.0",
"@hcengineering/ui": "^0.6.10",
"@hcengineering/setting": "^0.6.9",
"@hcengineering/presentation": "^0.6.2",
"@hcengineering/core": "^0.6.27",
"@hcengineering/view": "^0.6.8",
"@hcengineering/attachment-resources": "^0.6.0",
"@hcengineering/panel": "^0.6.12",
"@hcengineering/view-resources": "^0.6.0",
"@hcengineering/attachment": "^0.6.8",
"@hcengineering/notification": "^0.6.14",
"@hcengineering/login": "^0.6.7",
"@hcengineering/contact": "^0.6.19",
"@hcengineering/tags": "^0.6.11",
"@hcengineering/text-editor": "^0.6.0",
"@hcengineering/contact-resources": "^0.6.0"
}
}
@@ -1,5 +0,0 @@
module.exports = {
plugins: [
require('autoprefixer')
]
}
@@ -1,150 +0,0 @@
<!--
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
-->
<script lang="ts">
import { Employee, PersonAccount } from '@hcengineering/contact'
import { Data, generateId, getCurrentAccount, Ref } from '@hcengineering/core'
import { CollaboratorDocument, Document, DocumentVersionState } from '@hcengineering/document'
import { Card, getClient } from '@hcengineering/presentation'
import { UserBoxList } from '@hcengineering/contact-resources'
import { Button, createFocusManager, EditBox, FocusHandler } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import document from '../plugin'
export function canClose (): boolean {
return object.name === ''
}
const id = generateId()
const currentUser = getCurrentAccount() as PersonAccount
const object: Data<Document> = {
name: '',
versions: 0,
attachments: 0,
labels: 0,
comments: 0,
version: 0,
latest: 0.1,
approvers: [],
authors: [currentUser.person as Ref<Employee>],
reviewers: [],
requests: 0
}
const dispatch = createEventDispatcher()
const client = getClient()
async function createDocument () {
const docId = await client.createDoc(document.class.Document, document.space.Documents, object, id)
const contentAttachmentId: Ref<CollaboratorDocument> = generateId()
const versionId = await client.addCollection(
document.class.DocumentVersion,
document.space.Documents,
docId,
document.class.Document,
'versions',
{
content: '',
description: '',
impact: '',
reason: '',
state: DocumentVersionState.Draft,
version: 0.1,
attachments: 0,
comments: 0,
contentAttachmentId,
initialContentId: '' as Ref<CollaboratorDocument>
}
)
await client.addCollection(
document.class.CollaboratorDocument,
document.space.Documents,
versionId,
document.class.DocumentVersion,
'attachments',
{
file: contentAttachmentId,
name: 'content',
size: 0,
type: 'application/ydoc',
description: '',
pinned: false,
lastModified: Date.now()
},
contentAttachmentId
)
dispatch('close', id)
}
const manager = createFocusManager()
</script>
<FocusHandler {manager} />
<Card
label={document.string.CreateDocument}
okAction={createDocument}
canSave={object.name.length > 0}
on:close={() => {
dispatch('close')
}}
on:changeContent
>
<div class="flex-row-center clear-mins">
<div class="mr-3">
<Button icon={document.icon.Document} size={'medium'} kind={'link-bordered'} noFocus />
</div>
<EditBox
placeholder={document.string.DocumentNamePlaceholder}
bind:value={object.name}
kind={'large-style'}
autoFocus
focusIndex={1}
/>
</div>
<svelte:fragment slot="pool">
<UserBoxList
items={object.authors}
label={document.string.Authors}
emptyLabel={document.string.Authors}
kind={'regular'}
size={'large'}
width={'min-content'}
on:update={({ detail }) => (object.authors = detail)}
/>
<UserBoxList
items={object.approvers}
label={document.string.Approvers}
emptyLabel={document.string.Approvers}
kind={'regular'}
size={'large'}
width={'min-content'}
on:update={({ detail }) => (object.approvers = detail)}
/>
<UserBoxList
items={object.reviewers}
label={document.string.Reviewers}
emptyLabel={document.string.Reviewers}
kind={'regular'}
size={'large'}
width={'min-content'}
on:update={({ detail }) => (object.reviewers = detail)}
/>
</svelte:fragment>
</Card>
@@ -1,51 +0,0 @@
<!--
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
-->
<script lang="ts">
import { DocumentVersion } from '@hcengineering/document'
import { getMetadata } from '@hcengineering/platform'
import presentation from '@hcengineering/presentation'
import document from '../plugin'
import { CollaboratorEditor } from '@hcengineering/text-editor'
import { Markup } from '@hcengineering/core'
export let object: DocumentVersion
export let readonly = false
export let initialContentId: string | undefined = undefined
export let comparedVersion: Markup | undefined = undefined
const token = getMetadata(presentation.metadata.Token) ?? ''
const collaboratorURL = getMetadata(document.metadata.CollaboratorUrl) ?? ''
let editor: CollaboratorEditor
export function getHTML (): string | undefined {
return editor.getHTML()
}
</script>
{#key comparedVersion}
<CollaboratorEditor
documentId={object.contentAttachmentId}
{token}
{collaboratorURL}
{readonly}
on:content
{initialContentId}
{comparedVersion}
bind:this={editor}
/>
{/key}
@@ -1,39 +0,0 @@
<!--
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
-->
<script lang="ts">
import { WithLookup } from '@hcengineering/core'
import { Document, DocumentVersion } from '@hcengineering/document'
import { Icon } from '@hcengineering/ui'
import document from '../plugin'
export let value: WithLookup<Document>
const versions = (value.$lookup?.versions ?? []) as DocumentVersion[]
const lastVersion = versions.length > 0 ? versions[versions.length - 1] : undefined
</script>
<div class="flex-row-center">
<div class="flex-center p-1 content-dark-color flex-no-shrink mr-2-5">
<Icon icon={document.icon.Document} size={'medium'} />
</div>
<span class="overflow-label">
{value.name}
{#if lastVersion}
- {lastVersion?.version}
{/if}
</span>
</div>
@@ -1,49 +0,0 @@
<!--
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
-->
<script lang="ts">
import { WithLookup } from '@hcengineering/core'
import { Document } from '@hcengineering/document'
import { tooltip, Icon } from '@hcengineering/ui'
import { DocNavLink } from '@hcengineering/view-resources'
import document from '../plugin'
export let value: WithLookup<Document>
export let inline: boolean = false
export let disabled: boolean = false
export let accent: boolean = false
export let noUnderline: boolean = false
export let maxWidth = ''
</script>
{#if value}
<DocNavLink {disabled} object={value} {inline} {accent} {noUnderline} component={document.component.EditDoc}>
{#if inline}
<span class="antiMention" use:tooltip={{ label: document.string.Document }}>
@{value.name}-{value.version}
</span>
{:else}
<div class="flex-presenter" style:max-width={maxWidth} use:tooltip={{ label: document.string.Document }}>
<div class="icon">
<Icon icon={document.icon.Document} size={'small'} />
</div>
<span class="label nowrap" class:no-underline={noUnderline || disabled} class:fs-bold={accent}>
{value.name}-{value.version}
</span>
</div>
{/if}
</DocNavLink>
{/if}
@@ -1,53 +0,0 @@
<!--
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
-->
<script lang="ts">
import { Ref, WithLookup } from '@hcengineering/core'
import { Document, DocumentVersion } from '@hcengineering/document'
import { getClient } from '@hcengineering/presentation'
import { getPanelURI, Icon } from '@hcengineering/ui'
import document from '../plugin'
export let value: WithLookup<DocumentVersion>
export let inline = false
$: doc = value.$lookup?.attachedTo as Document
$: if (doc === undefined) {
getClient()
.findOne(document.class.Document, { _id: value.attachedTo as Ref<Document> })
.then((res) => {
doc = res as Document
})
}
</script>
{#if value}
<a
class="flex-presenter"
href="#{getPanelURI(document.component.EditDoc, value.attachedTo, value.attachedToClass, 'content')}"
class:inline-presenter={inline}
>
{#if !inline}
<div class="icon">
<Icon icon={document.icon.Document} size={'small'} />
</div>
{/if}
<span class="label">
{doc?.name} - {value.version}
</span>
</a>
{/if}
@@ -1,87 +0,0 @@
<!--
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
-->
<script lang="ts">
import { Doc, DocumentQuery } from '@hcengineering/core'
import { Document } from '@hcengineering/document'
import { ActionContext } from '@hcengineering/presentation'
import { Label, Loading, SearchEdit } from '@hcengineering/ui'
import view, { Viewlet, ViewletPreference } from '@hcengineering/view'
import { FilterButton, TableBrowser, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
import document from '../plugin'
export let query: DocumentQuery<Document> = {}
let search = ''
let resultQuery: DocumentQuery<Doc> = query
function updateResultQuery (search: string, query: DocumentQuery<Document>): void {
resultQuery = search === '' ? { ...query } : { ...query, $search: search }
}
let viewlet: Viewlet | undefined
let loading = true
let preference: ViewletPreference | undefined
</script>
<ActionContext
context={{
mode: 'browser'
}}
/>
<div class="antiPanel-component">
<div class="ac-header full divide caption-height">
<div class="ac-header__wrap-title mr-3">
<span class="ac-header__title"><Label label={document.string.Documents} /></span>
</div>
</div>
<div class="ac-header full divide search-start">
<div class="ac-header-full small-gap">
<SearchEdit bind:value={search} on:change={() => updateResultQuery(search, query)} />
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
<div class="buttons-divider" />
<FilterButton _class={document.class.Document} />
</div>
<div class="ac-header-full medium-gap">
<ViewletSelector
hidden
bind:viewlet
bind:preference
bind:loading
viewletQuery={{
attachTo: document.class.Document,
descriptor: view.viewlet.Table
}}
/>
<ViewletSettingButton bind:viewlet />
<!-- <ActionIcon icon={IconMoreH} size={'small'} /> -->
</div>
</div>
{#if loading}
<Loading />
{:else if viewlet}
<TableBrowser
_class={document.class.Document}
config={preference?.config ?? viewlet.config}
options={viewlet.options}
query={resultQuery}
totalQuery={query}
showNotification
/>
{/if}
</div>
@@ -1,580 +0,0 @@
<!--
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
-->
<script lang="ts">
import { Attachments } from '@hcengineering/attachment-resources'
import { Employee, PersonAccount } from '@hcengineering/contact'
import core, { Class, Doc, generateId, getCurrentAccount, Ref, WithLookup } from '@hcengineering/core'
import {
CollaboratorDocument,
Document,
DocumentRequest,
DocumentRequestKind,
DocumentVersion,
DocumentVersionState
} from '@hcengineering/document'
import notification from '@hcengineering/notification'
import { Panel } from '@hcengineering/panel'
import { getResource, translate } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import tags from '@hcengineering/tags'
import { CollaborationDiffViewer } from '@hcengineering/text-editor'
import view from '@hcengineering/view'
import { themeStore } from '@hcengineering/ui'
import {
Button,
Component,
EditBox,
eventToHTMLElement,
IconCheck,
IconClose,
IconEdit,
IconMoreH,
IconShare,
Label,
SelectPopup,
showPopup
} from '@hcengineering/ui'
import { ClassAttributeBar, ContextMenu, ParentsNavigator, UpDownNavigator } from '@hcengineering/view-resources'
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
import document from '../plugin'
import DocumentEditor from './DocumentEditor.svelte'
// import ControlPanel from './ControlPanel.svelte'
// import CopyToClipboard from './CopyToClipboard.svelte'
export let _id: Ref<Document>
export let _class: Ref<Class<Document>>
export let embedded = false
let lastId: Ref<Doc> = _id
const query = createQuery()
const dispatch = createEventDispatcher()
const client = getClient()
let documentObject: WithLookup<Document> | undefined
let name = ''
let innerWidth: number
const notificationClient = getResource(notification.function.GetNotificationClient).then((res) => res())
$: read(_id)
function read (_id: Ref<Doc>) {
if (lastId !== _id) {
const prev = lastId
lastId = _id
notificationClient.then((client) => client.read(prev))
}
}
const currentUser = getCurrentAccount() as PersonAccount
onDestroy(async () => {
notificationClient.then((client) => client.read(_id))
})
let requests: DocumentRequest[] = []
$: myRequests = requests.filter((it) => it.assignee === currentUser.person)
$: approveRequest = myRequests.find((it) => it.kind === DocumentRequestKind.Approve)
$: allApproveRequest = requests.find((it) => it.kind === DocumentRequestKind.Approve)
// $: changesRequest = myRequests.find((it) => it.kind === DocumentRequestKind.Changes)
// $: reviewRequest = myRequests.find((it) => it.kind === DocumentRequestKind.Review)
$: _id &&
_class &&
query.query(
_class,
{ _id },
async (result) => {
;[documentObject] = result
name = documentObject?.name ?? ''
requests = (documentObject.$lookup?.requests as DocumentRequest[]) ?? []
},
{
lookup: {
_id: {
requests: document.class.DocumentRequest
}
}
}
)
$: canSave = name.trim().length > 0
async function saveTitle (ev: Event) {
ev.preventDefault()
if (!documentObject || !canSave) {
return
}
const nameTrimmed = name.trim()
if (nameTrimmed.length > 0 && nameTrimmed !== documentObject.name) {
await client.update(documentObject, { name: nameTrimmed })
}
}
function showMenu (ev?: Event): void {
if (documentObject) {
showPopup(
ContextMenu,
{ object: documentObject, excludedActions: [view.action.Open] },
(ev as MouseEvent).target as HTMLElement
)
}
}
onMount(() => {
dispatch('open', { ignoreKeys: ['comments', 'name', 'reviewers'] })
})
const versionQuery = createQuery()
let versions: DocumentVersion[] = []
$: versionQuery.query(
document.class.DocumentVersion,
{ attachedTo: _id },
(res) => {
versions = res
if (autoSelect) {
version = versions[versions.length - 1]
}
},
{ sort: { version: 1 } }
)
let version: DocumentVersion | undefined
let compareTo: DocumentVersion | undefined
let info: any
let labels: Record<DocumentVersionState, string> = {
[DocumentVersionState.Draft]: '',
[DocumentVersionState.Approved]: '',
[DocumentVersionState.Rejected]: ''
}
async function updateLabels (lang: string): Promise<void> {
labels = {
[DocumentVersionState.Draft]: await translate(document.string.Draft, {}, lang),
[DocumentVersionState.Approved]: await translate(document.string.Approved, {}, lang),
[DocumentVersionState.Rejected]: await translate(document.string.Rejected, {}, lang)
}
}
updateLabels($themeStore.language)
$: {
const ifo: any = [
...versions.map((it) => ({
id: it._id as string,
text: `${it.version} - ${labels[it.state]} - ${new Date(it.modifiedOn).toDateString()} `
}))
]
info = ifo
}
function selectVersion (event: MouseEvent): void {
showPopup(
SelectPopup,
{
value: info,
placeholder: document.string.Version,
searchable: true
},
eventToHTMLElement(event),
(res) => {
if (res != null) {
version = versions.find((it) => it._id === res)
}
}
)
}
function selectCompareToVersion (event: MouseEvent): void {
showPopup(
SelectPopup,
{
value: [{ id: null, text: '-' }, ...info.slice(0, info.length - 1)],
placeholder: document.string.Version,
searchable: true
},
eventToHTMLElement(event),
(res) => {
if (res != null) {
compareTo = versions.find((it) => it._id === res)
} else if (res === null) {
compareTo = undefined
}
}
)
}
$: readonly = !documentObject?.authors.includes(currentUser.person as Ref<Employee>)
let autoSelect = true
async function doEdit (documentObject: Document): Promise<void> {
processing = true
// Looking for a draft version
const draft = versions.find((it) => it.state === DocumentVersionState.Draft)
const lastVersion = versions[versions.length - 1]
if (draft === undefined) {
// We need to create draft document.
const newVersion = Math.round(documentObject.latest * 1000 + 100) / 1000
const versionId: Ref<DocumentVersion> = generateId()
const contentAttachmentId: Ref<CollaboratorDocument> = generateId()
const ops = client
.apply(documentObject._id)
.match(document.class.Document, { _id: documentObject._id, latest: documentObject.latest })
ops.update(documentObject, { latest: newVersion })
ops.addCollection(
document.class.DocumentVersion,
documentObject.space,
documentObject._id,
documentObject._class,
'versions',
{
content: lastVersion.content,
description: '',
impact: '',
reason: '',
state: DocumentVersionState.Draft,
version: newVersion,
attachments: 0,
comments: 0,
initialContentId: lastVersion.contentAttachmentId,
contentAttachmentId
},
versionId
)
ops.addCollection(
document.class.CollaboratorDocument,
documentObject.space,
versionId,
document.class.DocumentVersion,
'attachments',
{
file: contentAttachmentId,
name: 'content',
size: 0,
type: 'application/ydoc',
description: '',
pinned: false,
lastModified: Date.now()
},
contentAttachmentId
)
if (await ops.commit()) {
// We should have a draft created by someone else.
version = undefined
autoSelect = true
}
}
processing = false
}
let processing = false
const updateRequests = async (kind: DocumentRequestKind): Promise<void> => {
processing = true
if (documentObject === undefined) {
return
}
const requests = await client.findAll(document.class.DocumentRequest, {
attachedTo: documentObject?._id,
kind
})
for (const a of documentObject?.approvers ?? []) {
const ex = requests.find((it) => it.assignee === a)
if (ex === undefined) {
await client.addCollection(
document.class.DocumentRequest,
documentObject.space,
documentObject._id,
documentObject._class,
'requests',
{
assignee: a,
kind
}
)
}
}
if (version) {
await client.update(version, {
content: editor.getHTML()
})
}
processing = false
}
let editor: DocumentEditor
const updateState = async (state: DocumentVersionState): Promise<void> => {
processing = true
if (documentObject === undefined) {
return
}
const draft = versions.find((it) => it.state === DocumentVersionState.Draft)
if (draft !== undefined) {
// We need to create draft document.
const newVersion = documentObject.version + 1
const ops = client
.apply(documentObject._id)
.match(document.class.Document, { _id: documentObject._id, latest: documentObject.latest })
if (state === DocumentVersionState.Approved) {
ops.update(documentObject, { latest: newVersion, version: newVersion })
ops.update(draft, { version: newVersion, state })
} else {
ops.update(draft, { state })
}
// Remove all requests
if (await ops.commit()) {
const docs = await client.findAll(document.class.DocumentRequest, { attachedTo: documentObject._id })
for (const d of docs) {
client.remove(d)
}
}
}
processing = false
}
async function switchToDraft (): Promise<void> {
const requests = await client.findAll(document.class.DocumentRequest, { attachedTo: documentObject?._id })
for (const r of requests) {
client.remove(r)
}
}
</script>
{#if documentObject !== undefined}
<Panel
object={documentObject}
isHeader
isAside={true}
isSub={false}
{embedded}
bind:innerWidth
floatAside={false}
useMaxWidth={true}
on:open
on:close={() => dispatch('close')}
>
<svelte:fragment slot="navigator">
<UpDownNavigator element={documentObject} />
<ParentsNavigator element={documentObject} />
</svelte:fragment>
<svelte:fragment slot="header">
<span class="fs-title flex-row-center flex-shrink gap-1-5">
<EditBox
bind:value={name}
placeholder={document.string.DocumentNamePlaceholder}
kind="large-style"
on:blur={(evt) => saveTitle(evt)}
/>
<div class="p-1">-</div>
<Button loading={processing} kind={'link-bordered'} on:click={selectVersion} disabled={info.length < 2}>
<svelte:fragment slot="content">
{#if version}
{version.version} - {labels[version.state]}
{:else}
<Label label={document.string.Draft} />
{/if}
</svelte:fragment>
</Button>
<Button
loading={processing}
kind={'link-bordered'}
on:click={selectCompareToVersion}
disabled={info.length < 2}
>
<svelte:fragment slot="content">
{#if compareTo}
{compareTo.version} - {labels[compareTo.state]}
{:else}
<Label label={document.string.CompareTo} />
{/if}
</svelte:fragment>
</Button>
</span>
</svelte:fragment>
<svelte:fragment slot="tools">
{#if version && version?.state !== DocumentVersionState.Draft}
<Button
loading={processing}
kind={'link-bordered'}
label={document.string.CreateDraft}
on:click={() => {
if (documentObject) {
doEdit(documentObject)
}
}}
icon={IconEdit}
size={'medium'}
/>
{/if}
{#if !readonly && version && version?.state === DocumentVersionState.Draft && version.version === documentObject.latest && !allApproveRequest}
<Button
loading={processing}
kind={'link-bordered'}
label={document.string.SendForApproval}
on:click={() => updateRequests(DocumentRequestKind.Approve)}
icon={IconShare}
size={'medium'}
disabled={documentObject?.approvers?.length === 0}
/>
<!-- <Button
loading={processing}
kind={'link-bordered'}
label={document.string.SendForReview}
on:click={() => updateRequests(DocumentRequestKind.Review)}
icon={IconShare}
size={'medium'}
disabled={documentObject?.reviewers?.length === 0}
/> -->
{/if}
{#if version?.state === DocumentVersionState.Draft && approveRequest}
<Button
loading={processing}
kind={'link-bordered'}
label={document.string.Approve}
on:click={() => updateState(DocumentVersionState.Approved)}
icon={IconCheck}
size={'medium'}
/>
<Button
loading={processing}
kind={'link-bordered'}
label={document.string.Reject}
on:click={() => updateState(DocumentVersionState.Rejected)}
icon={IconClose}
size={'medium'}
/>
{#if !readonly}
<Button
loading={processing}
kind={'link-bordered'}
label={document.string.Draft}
on:click={() => switchToDraft()}
icon={IconEdit}
size={'medium'}
/>
{/if}
{/if}
<Button icon={IconMoreH} kind={'ghost'} size={'medium'} on:click={showMenu} />
</svelte:fragment>
<div class="description-preview select-text mt-2 emphasized">
{#if version && version.state === DocumentVersionState.Draft && approveRequest === undefined}
{#key version?._id}
<!-- suggestMode={mode === 'suggest'} -->
<DocumentEditor
object={version}
initialContentId={version.initialContentId}
comparedVersion={compareTo?.content ?? versions[versions.length - 2]?.content}
readonly={false}
bind:this={editor}
/>
{/key}
{:else if version}
{#key [compareTo?.content, version.content]}
<CollaborationDiffViewer content={version.content} comparedVersion={compareTo?.content} />
{/key}
{/if}
</div>
<div class="p-1 mt-6">
<Attachments
objectId={documentObject._id}
space={documentObject.space}
_class={documentObject._class}
attachments={documentObject.attachments ?? 0}
/>
</div>
<svelte:fragment slot="custom-attributes">
<ClassAttributeBar
object={documentObject}
_class={documentObject._class}
to={core.class.Doc}
ignoreKeys={['name', 'reviewers']}
{readonly}
/>
<div class="doc-divider" />
<div class="popupPanel-body__aside-grid">
<span class="labelTop">
<Label label={document.string.Labels} />
</span>
<div class="flex">
<Component
is={tags.component.TagsAttributeEditor}
props={{ object: documentObject, label: document.string.AddLabel }}
/>
</div>
<div class="divider" />
<span class="labelOnPanel">
<Label label={document.string.LastRevision} />
</span>
<span>{documentObject?.latest}</span>
</div>
</svelte:fragment>
</Panel>
{/if}
<style lang="scss">
.description-preview {
color: var(--content-color);
line-height: 150%;
// overflow: auto;
}
.doc-divider {
flex-shrink: 0;
margin: 0 0 0.5rem;
height: 1px;
background-color: var(--theme-divider-color);
}
.emphasized {
padding: 1rem;
background-color: var(--theme-bg-color);
border: 1px solid var(--divider-color);
border-radius: 0.5rem;
transition: border-color 0.1s var(--timing-main), box-shadow 0.1s var(--timing-main);
&:focus-within {
box-shadow: 0 0 0 3px var(--accented-button-outline);
}
}
</style>
@@ -1,9 +0,0 @@
<script lang="ts">
import { Employee, PersonAccount } from '@hcengineering/contact'
import { Ref, getCurrentAccount } from '@hcengineering/core'
import Documents from './Documents.svelte'
const currentUser = (getCurrentAccount() as PersonAccount).person as Ref<Employee>
</script>
<Documents query={{ authors: currentUser }} />
@@ -1,35 +0,0 @@
<!--
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { Button, showPopup, IconAdd } from '@hcengineering/ui'
import document from '../plugin'
import CreateDocument from './CreateDocument.svelte'
async function newDocument (): Promise<void> {
showPopup(CreateDocument, {}, 'top')
}
</script>
<div class="antiNav-subheader">
<Button
icon={IconAdd}
label={document.string.CreateDocument}
justify={'left'}
width={'100%'}
kind={'accented'}
size={'large'}
on:click={newDocument}
/>
</div>
@@ -1,64 +0,0 @@
<!--
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
-->
<script lang="ts">
import { WithLookup } from '@hcengineering/core'
import { DocumentVersion, DocumentVersionState } from '@hcengineering/document'
import { EastSideColor, FernColor, Label, SeaBuckthornColor } from '@hcengineering/ui'
import document from '../plugin'
export let value: WithLookup<DocumentVersion>
</script>
{#if value}
<div class="status-container">
{#if value.state === DocumentVersionState.Draft}
<div class="status p-1" style:background-color={EastSideColor}>
<Label label={document.string.Draft} />
</div>
{/if}
{#if value.state === DocumentVersionState.Approved}
<div class="status p-1" style:background-color={SeaBuckthornColor}>
<Label label={document.string.Approved} />
</div>
{/if}
{#if value.state === DocumentVersionState.Rejected}
<div class="status p-1" style:background-color={FernColor}>
<Label label={document.string.Rejected} />
</div>
{/if}
</div>
{/if}
<style lang="scss">
.status-container {
display: flex;
.status {
border-radius: 8px;
margin: 0.1rem;
font-weight: 500;
font-size: 10px;
text-transform: uppercase;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>
@@ -1,40 +0,0 @@
<!--
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
-->
<script lang="ts">
import { WithLookup } from '@hcengineering/core'
import { Document, DocumentVersion } from '@hcengineering/document'
export let value: WithLookup<Document>
let lastVersion: DocumentVersion | undefined
$: if (value.$lookup?.versions !== undefined) {
let vv = -1
let dv: DocumentVersion | undefined
for (const v of value.$lookup.versions as DocumentVersion[]) {
if (v.version > vv) {
dv = v
vv = v.version
}
}
lastVersion = dv
}
</script>
{#if lastVersion}
{lastVersion.version}
{/if}
@@ -1,25 +0,0 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'var(--caption-color)'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path
d="M13.3,6.5l1.9-1.9c1.1-1.1,1.1-2.8,0-3.8c-1.1-1.1-2.8-1.1-3.8,0L9.5,2.7C10.4,4.3,11.7,5.6,13.3,6.5z M12.3,7.6c-1.6-1-2.9-2.3-3.8-3.8l-6.3,6.3l0,0C1.5,10.7,1.2,11,1,11.4c-0.2,0.4-0.3,0.8-0.5,1.6l-0.4,2c-0.1,0.5-0.1,0.7,0,0.9 c0.1,0.1,0.4,0.1,0.9,0l2-0.4c0.8-0.2,1.3-0.3,1.6-0.5c0.4-0.2,0.7-0.5,1.3-1.1L12.3,7.6z"
/>
</svg>
-88
View File
@@ -1,88 +0,0 @@
//
// Copyright © 2022 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 { Class, Client, DocumentQuery, Ref, RelatedDocument, WithLookup } from '@hcengineering/core'
import { Document } from '@hcengineering/document'
import { Resources } from '@hcengineering/platform'
import { ObjectSearchResult } from '@hcengineering/presentation'
import CreateDocument from './components/CreateDocument.svelte'
import DocumentPresenter from './components/DocumentPresenter.svelte'
import DocumentVersionPresenter from './components/DocumentVersionPresenter.svelte'
import Documents from './components/Documents.svelte'
import MyDocuments from './components/MyDocuments.svelte'
import EditDoc from './components/EditDoc.svelte'
import DocumentItem from './components/DocumentItem.svelte'
import NewDocumentHeader from './components/NewDocumentHeader.svelte'
import Status from './components/Status.svelte'
import Version from './components/Version.svelte'
import document from './plugin'
const toObjectSearchResult = (e: WithLookup<Document>): ObjectSearchResult => ({
doc: e,
title: e.name,
icon: document.icon.Document,
component: DocumentItem
})
async function queryDocument (
_class: Ref<Class<Document>>,
client: Client,
search: string,
filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }
): Promise<ObjectSearchResult[]> {
const q: DocumentQuery<Document> = { name: { $like: `%${search}%` } }
if (filter?.in !== undefined || filter?.nin !== undefined) {
q._id = {}
if (filter.in !== undefined) {
q._id.$in = filter.in?.map((it) => it._id as Ref<Document>)
}
if (filter.nin !== undefined) {
q._id.$nin = filter.nin?.map((it) => it._id as Ref<Document>)
}
}
return (
await client.findAll(_class, q, {
limit: 200,
lookup: {
_id: {
versions: document.class.DocumentVersion
}
}
})
).map(toObjectSearchResult)
}
export default async (): Promise<Resources> => ({
component: {
CreateDocument,
DocumentPresenter,
Documents,
EditDoc,
DocumentVersionPresenter,
NewDocumentHeader,
MyDocuments,
Status,
Version
},
completion: {
DocumentQuery: async (
client: Client,
query: string,
filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }
) => await queryDocument(document.class.Document, client, query, filter)
}
})
-83
View File
@@ -1,83 +0,0 @@
//
// Copyright © 2022 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 document, { documentId } from '@hcengineering/document'
import { IntlString, mergeIds } from '@hcengineering/platform'
import { AnyComponent } from '@hcengineering/ui'
export default mergeIds(documentId, document, {
component: {
EditDoc: '' as AnyComponent,
MyDocuments: '' as AnyComponent,
NewDocumentHeader: '' as AnyComponent,
Status: '' as AnyComponent,
Version: '' as AnyComponent,
Revision: '' as AnyComponent
},
string: {
Apply: '' as IntlString,
DocumentNamePlaceholder: '' as IntlString,
Name: '' as IntlString,
Cancel: '' as IntlString,
Documents: '' as IntlString,
DocumentCreateLabel: '' as IntlString,
EditorPlaceholder: '' as IntlString,
Versions: '' as IntlString,
Document: '' as IntlString,
SearchDocument: '' as IntlString,
Version: '' as IntlString,
Revision: '' as IntlString,
NoVersions: '' as IntlString,
NoBaseVersion: '' as IntlString,
CreateAnVersion: '' as IntlString,
CreateDocumentVersion: '' as IntlString,
Approvers: '' as IntlString,
Status: '' as IntlString,
LastRevision: '' as IntlString,
DocumentApplication: '' as IntlString,
MyDocuments: '' as IntlString,
Library: '' as IntlString,
Labels: '' as IntlString,
Authors: '' as IntlString,
AddLabel: '' as IntlString,
DocumentVersionPlaceholder: '' as IntlString,
PendingReview: '' as IntlString,
Latest: '' as IntlString,
Draft: '' as IntlString,
Approved: '' as IntlString,
Rejected: '' as IntlString,
Description: '' as IntlString,
DescriptionPlaceholder: '' as IntlString,
Baseline: '' as IntlString,
Reviewers: '' as IntlString,
ViewMode: '' as IntlString,
EditMode: '' as IntlString,
SuggestMode: '' as IntlString,
CreateDraft: '' as IntlString,
SendForApproval: '' as IntlString,
SendForReview: '' as IntlString,
Requests: '' as IntlString,
Approve: '' as IntlString,
Reject: '' as IntlString,
CompareTo: '' as IntlString
}
})
@@ -1,5 +0,0 @@
const sveltePreprocess = require('svelte-preprocess')
module.exports = {
preprocess: sveltePreprocess()
};
-16
View File
@@ -1,16 +0,0 @@
{
"compilerOptions": {
"moduleResolution": "node",
"target": "esnext",
"module": "esnext",
"declaration": true,
"outDir": "./lib",
"strict": true,
"skipLibCheck": true,
"esModuleInterop": true,
"lib": [
"esnext",
"dom"
]
}
}
-7
View File
@@ -1,7 +0,0 @@
module.exports = {
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/config/eslint.config.json'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
}
}
-4
View File
@@ -1,4 +0,0 @@
*
!/lib/**
!CHANGELOG.md
/lib/**/__tests__/
-18
View File
@@ -1,18 +0,0 @@
// The "rig.json" file directs tools to look for their config files in an external package.
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
/**
* (Required) The name of the rig package to inherit from.
* It should be an NPM package name with the "-rig" suffix.
*/
"rigPackageName": "@hcengineering/platform-rig"
/**
* (Optional) Selects a config profile from the rig package. The name must consist of
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
* If omitted, then the "default" profile will be used."
*/
// "rigProfile": "your-profile-name"
}
-41
View File
@@ -1,41 +0,0 @@
{
"name": "@hcengineering/document",
"version": "0.6.0",
"main": "lib/index.js",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "heft build",
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"lint": "eslint src",
"format": "prettier --write src && eslint --fix src"
},
"devDependencies": {
"@hcengineering/platform-rig": "^0.6.0",
"@types/heft-jest": "^1.0.3",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-n": "^15.4.0",
"eslint": "^8.26.0",
"@typescript-eslint/parser": "^5.41.0",
"eslint-config-standard-with-typescript": "^23.0.0",
"prettier": "^2.7.1",
"@rushstack/heft": "^0.47.9",
"typescript": "^4.3.5"
},
"dependencies": {
"@hcengineering/platform": "^0.6.9",
"@hcengineering/ui": "^0.6.10",
"@hcengineering/core": "^0.6.27",
"@hcengineering/view": "^0.6.8",
"@hcengineering/contact": "^0.6.19",
"@hcengineering/notification": "^0.6.14",
"@hcengineering/attachment": "^0.6.8"
},
"repository": "https://github.com/hcengineering/anticrm",
"publishConfig": {
"registry": "https://npm.pkg.github.com"
}
}
-146
View File
@@ -1,146 +0,0 @@
//
// Copyright © 2022 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 { Attachment } from '@hcengineering/attachment'
import { Employee } from '@hcengineering/contact'
import { AttachedDoc, Class, Doc, Markup, Ref, Space } from '@hcengineering/core'
import type { Asset, Metadata, Plugin } from '@hcengineering/platform'
import { IntlString, plugin } from '@hcengineering/platform'
import type { AnyComponent } from '@hcengineering/ui'
/**
* @public
*/
export interface Document extends Doc {
name: string
version: number // Latest approved version of document
latest: number // Latest draft version
// Collection of versions of this document.
versions: number
attachments?: number
comments?: number
labels?: number
// List of authors, who could edit the version until it will be published
// Combined with reviewers.
authors: Ref<Employee>[]
// List of persons who revieded version
reviewers: Ref<Employee>[]
// List of persions who approved version.
approvers: Ref<Employee>[]
requests: number
}
/**
* @public
*/
export enum DocumentVersionState {
Draft,
Approved,
Rejected
}
/**
* @public
*/
export interface DocumentVersion extends AttachedDoc {
version: number // Uniq version of document.
description: Markup
reason: Markup
impact: Markup
state: DocumentVersionState
// Defined only if document being proposed for review or approval
content: Markup
contentAttachmentId: Ref<CollaboratorDocument>
initialContentId: Ref<CollaboratorDocument> | undefined
// Attachments contain a CollaboratorDocument with content hold in S3
attachments: number
comments: number
}
/**
* A collaborative document handle, with a minio document in collaborative mode.
* @public
*/
export interface CollaboratorDocument extends Attachment {}
/**
* @public
*/
export enum DocumentRequestKind {
Review, // Review requested
Approve, // Approve requested
Changes // Changes requested
}
/**
* @public
*/
export interface DocumentRequest extends AttachedDoc {
kind: DocumentRequestKind
assignee: Ref<Employee>
message?: Markup
}
/**
* @public
*/
export const documentId = 'document' as Plugin
/**
* @public
*/
const documentPlugin = plugin(documentId, {
class: {
Document: '' as Ref<Class<Document>>,
DocumentVersion: '' as Ref<Class<DocumentVersion>>,
DocumentRequest: '' as Ref<Class<DocumentRequest>>,
CollaboratorDocument: '' as Ref<Class<CollaboratorDocument>>
},
component: {
CreateDocument: '' as AnyComponent
},
icon: {
DocumentApplication: '' as Asset,
NewDocument: '' as Asset,
Document: '' as Asset,
Library: '' as Asset
},
space: {
Documents: '' as Ref<Space>
},
app: {
Documents: '' as Ref<Doc>
},
string: {
CreateDocument: '' as IntlString
},
ids: {
NO_VERSION: '' as Ref<DocumentVersion>
},
metadata: {
CollaboratorUrl: '' as Metadata<string>
}
})
export default documentPlugin
-9
View File
@@ -1,9 +0,0 @@
{
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib",
"lib": ["esnext", "dom"]
}
}
-7
View File
@@ -1,7 +0,0 @@
module.exports = {
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/config/eslint.config.json'],
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json'
}
}
-4
View File
@@ -1,4 +0,0 @@
*
!/lib/**
!CHANGELOG.md
/lib/**/__tests__/
-9
View File
@@ -1,9 +0,0 @@
FROM node:18-alpine
WORKDIR /usr/src/app
COPY bundle.js ./
EXPOSE 3078
CMD [ "node", "bundle.js" ]
-20
View File
@@ -1,20 +0,0 @@
#!/bin/bash
#
# Copyright © 2020, 2021 Anticrm Platform Contributors.
# Copyright © 2021 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.
#
rushx bundle
rushx docker:build
rushx docker:push
-18
View File
@@ -1,18 +0,0 @@
// The "rig.json" file directs tools to look for their config files in an external package.
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
{
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
/**
* (Required) The name of the rig package to inherit from.
* It should be an NPM package name with the "-rig" suffix.
*/
"rigPackageName": "@hcengineering/platform-rig"
/**
* (Optional) Selects a config profile from the rig package. The name must consist of
* lowercase alphanumeric words separated by hyphens, for example "sample-profile".
* If omitted, then the "default" profile will be used."
*/
// "rigProfile": "your-profile-name"
}
-52
View File
@@ -1,52 +0,0 @@
{
"name": "@hcengineering/pod-collaborator",
"version": "0.6.0",
"main": "lib/index.js",
"author": "Anticrm Platform Contributors",
"license": "EPL-2.0",
"scripts": {
"build": "heft build",
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"bundle": "esbuild src/__start.ts --bundle --platform=node > bundle.js",
"docker:build": "docker build -t hardcoreeng/collaborator .",
"docker:staging": "../../common/scripts/docker_tag.sh hardcoreeng/collaborator staging",
"docker:push": "../../common/scripts/docker_tag.sh hardcoreeng/collaborator",
"run-local": "cross-env SECRET=secret MINIO_ENDPOINT=localhost MINIO_ACCESS_KEY=minioadmin MINIO_SECRET_KEY=minioadmin ts-node src/__start.ts",
"run-bundle": "cross-env SECRET=secret MINIO_ENDPOINT=localhost MINIO_ACCESS_KEY=minioadmin MINIO_SECRET_KEY=minioadmin node ./bundle.js",
"lint": "eslint src",
"format": "prettier --write src && eslint --fix src"
},
"devDependencies": {
"cross-env": "~7.0.3",
"@hcengineering/platform-rig": "^0.6.0",
"@types/heft-jest": "^1.0.3",
"@types/node": "~16.11.12",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-n": "^15.4.0",
"eslint": "^8.26.0",
"esbuild": "^0.16.14",
"@typescript-eslint/parser": "^5.41.0",
"eslint-config-standard-with-typescript": "^23.0.0",
"prettier": "^2.7.1",
"ts-node": "^10.8.0",
"@rushstack/heft": "^0.47.9",
"typescript": "^4.3.5",
"@types/ws": "^8.5.3"
},
"dependencies": {
"@hcengineering/core": "^0.6.27",
"@hcengineering/account": "^0.6.0",
"@hcengineering/platform": "^0.6.9",
"@hcengineering/server-tool": "^0.6.0",
"@hcengineering/server-token": "^0.6.6",
"@hcengineering/server-core": "^0.6.1",
"lib0": "~0.2.52",
"y-protocols": "^1.0.5",
"ws": "^8.10.0",
"yjs": "^13.5.52",
"@hcengineering/minio": "^0.6.0"
}
}
-50
View File
@@ -1,50 +0,0 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 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 { setMetadata } from '@hcengineering/platform'
import serverToken from '@hcengineering/server-token'
import { metricsContext } from './metrics'
import { start } from './server'
import { MinioService } from '@hcengineering/minio'
import config from './config'
setMetadata(serverToken.metadata.Secret, config.Secret)
let minioPort = 9000
let minioEndpoint = config.MinioEndpoint
const sp = minioEndpoint.split(':')
if (sp.length > 1) {
minioEndpoint = sp[0]
minioPort = parseInt(sp[1])
}
const minio = new MinioService({
endPoint: minioEndpoint,
port: minioPort,
useSSL: false,
accessKey: config.MinioAccessKey,
secretKey: config.MinioSecretKey
})
const server = start(metricsContext, config.Port, minio)
const close = (): void => {
server()
}
process.on('SIGINT', close)
process.on('SIGTERM', close)
process.on('exit', close)
-68
View File
@@ -1,68 +0,0 @@
//
// Copyright © 2022 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.
//
interface Config {
ServiceID: string
Secret: string
Interval: number
Port: number
MinioEndpoint: string
MinioAccessKey: string
MinioSecretKey: string
}
const envMap: { [key in keyof Config]: string } = {
ServiceID: 'SERVICE_ID',
Secret: 'SECRET',
Interval: 'INTERVAL',
Port: 'COLLABORATOR_PORT',
MinioEndpoint: 'MINIO_ENDPOINT',
MinioAccessKey: 'MINIO_ACCESS_KEY',
MinioSecretKey: 'MINIO_SECRET_KEY'
}
const required: Array<keyof Config> = [
'Secret',
'ServiceID',
'Port',
'MinioEndpoint',
'MinioAccessKey',
'MinioSecretKey'
]
const config: Config = (() => {
const params: Partial<Config> = {
Secret: process.env[envMap.Secret],
ServiceID: process.env[envMap.ServiceID] ?? 'collaborator-service',
Interval: parseInt(process.env[envMap.Interval] ?? '30000'),
Port: parseInt(process.env[envMap.Port] ?? '3078'),
MinioEndpoint: process.env[envMap.MinioEndpoint],
MinioAccessKey: process.env[envMap.MinioAccessKey],
MinioSecretKey: process.env[envMap.MinioSecretKey]
}
const missingEnv = required.filter((key) => params[key] === undefined).map((key) => envMap[key])
if (missingEnv.length > 0) {
throw Error(`Missing env variables: ${missingEnv.join(', ')}`)
}
return params as Config
})()
export default config
-17
View File
@@ -1,17 +0,0 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021, 2022 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.
//
export { start } from './server'
-34
View File
@@ -1,34 +0,0 @@
import { MeasureMetricsContext, metricsToString, newMetrics } from '@hcengineering/core'
import { writeFile } from 'fs/promises'
const metricsFile = process.env.METRICS_FILE
const metricsConsole = (process.env.METRICS_CONSOLE ?? 'false') === 'true'
const METRICS_UPDATE_INTERVAL = !metricsConsole ? 1000 : 30000
const metrics = newMetrics()
export const metricsContext = new MeasureMetricsContext('System', {}, metrics)
if (metricsFile !== undefined || metricsConsole) {
console.info('storing measurements into local file', metricsFile)
let oldMetricsValue = ''
const intTimer = setInterval(() => {
const val = metricsToString(metrics, 'System', 140)
if (val !== oldMetricsValue) {
oldMetricsValue = val
if (metricsFile !== undefined) {
writeFile(metricsFile, val).catch((err) => console.error(err))
}
if (metricsConsole) {
console.info('METRICS:', val)
}
}
}, METRICS_UPDATE_INTERVAL)
const closeTimer = (): void => {
clearInterval(intTimer)
}
process.on('SIGINT', closeTimer)
process.on('SIGTERM', closeTimer)
}
-80
View File
@@ -1,80 +0,0 @@
import { MeasureContext } from '@hcengineering/core'
import { UNAUTHORIZED } from '@hcengineering/platform'
import { Token, decodeToken } from '@hcengineering/server-token'
import { IncomingMessage, createServer } from 'http'
import WebSocket, { WebSocketServer } from 'ws'
import { setupWSConnection } from './yserver'
import { MinioService } from '@hcengineering/minio'
/**
* @public
* @param sessionFactory -
* @param port -
* @param host -
*/
export function start (ctx: MeasureContext, port: number, minio: MinioService, host?: string): () => void {
console.log(`starting server on port ${port} ...`)
const wss = new WebSocketServer({
noServer: true,
perMessageDeflate: {
zlibDeflateOptions: {
// See zlib defaults.
chunkSize: 1024,
memLevel: 7,
level: 3
},
zlibInflateOptions: {
chunkSize: 10 * 1024
},
// Below options specified as default values.
concurrencyLimit: 10, // Limits zlib concurrency for perf.
threshold: 1024 // Size (in bytes) below which messages
// should not be compressed if context takeover is disabled.
}
})
// eslint-disable-next-line @typescript-eslint/no-misused-promises
wss.on(
'connection',
(ws: WebSocket, request: IncomingMessage, token: Token, documentId: string, initialContentId: string) => {
setupWSConnection(ws, request, documentId, token, minio, initialContentId)
}
)
const server = createServer()
server.on('upgrade', (request: IncomingMessage, socket: any, head: Buffer) => {
try {
const parsedUrl = new URL('http://host' + (request.url ?? ''))
const token = parsedUrl.searchParams.get('token')
const payload = decodeToken(token ?? '')
const documentId = parsedUrl.searchParams.get('documentId') as string
console.log('client connected with payload', payload, documentId)
const initialContentId = parsedUrl.searchParams.get('initialContentId') as string
wss.handleUpgrade(request, socket, head, (ws) =>
wss.emit('connection', ws, request, payload, documentId, initialContentId)
)
} catch (err) {
wss.handleUpgrade(request, socket, head, (ws) => {
const resp = {
id: -1,
error: UNAUTHORIZED,
result: 'hello'
}
ws.send(JSON.stringify(resp))
ws.onmessage = (msg) => {
const resp = {
error: UNAUTHORIZED
}
ws.send(JSON.stringify(resp))
}
})
}
})
server.listen(port, host)
return () => {
server.close()
}
}
-351
View File
@@ -1,351 +0,0 @@
import { applyAwarenessUpdate, Awareness, encodeAwarenessUpdate, removeAwarenessStates } from 'y-protocols/awareness'
import { readSyncMessage, writeSyncStep1, writeUpdate } from 'y-protocols/sync'
import { applyUpdate, Doc, encodeStateAsUpdate } from 'yjs'
import { createDecoder, readVarUint, readVarUint8Array } from 'lib0/decoding'
import { createEncoder, length, toUint8Array, writeVarUint, writeVarUint8Array } from 'lib0/encoding'
import { Token } from '@hcengineering/server-token'
import WebSocket from 'ws'
import { MinioService } from '@hcengineering/minio'
const wsReadyStateConnecting = 0
const wsReadyStateOpen = 1
const wsReadyStateClosing = 2 // eslint-disable-line
const wsReadyStateClosed = 3 // eslint-disable-line
// disable gc when using snapshots!
const gcEnabled = process.env.GC !== 'false' && process.env.GC !== '0'
/**
* @public
*/
export interface YPersistence {
bindState: (
documentId: string,
ydoc: WSSharedDoc,
token: Token,
minio: MinioService,
initialContentId: string
) => Promise<void>
writeState: (documentId: string, ydoc: WSSharedDoc, token: Token) => Promise<void>
provider: any
}
/**
* @public
*/
let persistence: YPersistence
persistence = {
provider: 'platform',
bindState: async (
documentId: string,
ydoc: WSSharedDoc,
token: Token,
minio: MinioService,
initialContentId: string
): Promise<void> => {
try {
ydoc.minio = minio
let minioDocument: Buffer | undefined
try {
minioDocument = Buffer.concat(await minio.read(token.workspace, documentId))
console.log('bind for document', documentId, token.email)
} catch (err: any) {
if (initialContentId !== undefined && initialContentId.length > 0) {
// Try first take existing document.
const existingDoc = getYDoc(initialContentId, token, true, minio, initialContentId, false)
if (existingDoc !== undefined) {
const newUpdates = encodeStateAsUpdate(existingDoc)
minioDocument = Buffer.from(newUpdates.buffer)
console.log('bind for existing document', documentId, token.email)
} else {
minioDocument = Buffer.concat(await minio.read(token.workspace, initialContentId))
console.log('bind for initial document', documentId, token.email, initialContentId)
}
}
}
if (minioDocument !== undefined && minioDocument.length > 0) {
try {
const uint8arr = new Uint8Array(minioDocument)
applyUpdate(ydoc, uint8arr)
} catch (err) {
console.error(err)
}
}
} catch (err: any) {
console.error(err)
}
},
writeState: async (documentId: string, ydoc: WSSharedDoc, token: Token): Promise<void> => {
try {
const newUpdates = encodeStateAsUpdate(ydoc)
const buffer = Buffer.from(newUpdates.buffer)
await ydoc?.minio?.put(token.workspace, documentId, buffer)
console.log('state written for', documentId, token.email)
} catch (err: any) {
console.error(err)
}
}
}
/**
* @public
*/
export function setPersistence (persistence_: YPersistence): void {
persistence = persistence_
}
/**
* @public
*/
export const getPersistence = (): YPersistence | null => persistence
/**
* @public
*/
export const docs: Map<string, WSSharedDoc> = new Map()
const messageSync = 0
const messageAwareness = 1
// const messageAuth = 2
/**
* @param {Uint8Array} update
* @param {any} origin
* @param {WSSharedDoc} doc
*/
const updateHandler = (update: Uint8Array, origin: any, doc: WSSharedDoc): any => {
const encoder = createEncoder()
writeVarUint(encoder, messageSync)
writeUpdate(encoder, update)
const message = toUint8Array(encoder)
doc.conns.forEach((_, conn) => send(doc, conn, message))
}
export interface ConnectionEntry {
ids: Set<number>
token: Token
}
class WSSharedDoc extends Doc {
conns = new Map<WebSocket, ConnectionEntry>()
awareness: Awareness
minio?: MinioService
/**
* @param {{ added: Array<number>, updated: Array<number>, removed: Array<number> }} changes
* @param {Object | null} conn Origin is the connection that made the change
*/
awarenessChangeHandler = (
{ added, updated, removed }: { added: Array<number>, updated: Array<number>, removed: Array<number> },
conn: WebSocket | null
): void => {
const changedClients = added.concat(updated, removed)
if (conn !== null) {
const connControlledIDs = /** @type {Set<number>} */ this.conns.get(conn)
if (connControlledIDs !== undefined) {
added.forEach((clientID) => {
connControlledIDs.ids.add(clientID)
})
removed.forEach((clientID) => {
connControlledIDs.ids.delete(clientID)
})
}
}
// broadcast awareness update
const encoder = createEncoder()
writeVarUint(encoder, messageAwareness)
writeVarUint8Array(encoder, encodeAwarenessUpdate(this.awareness, changedClients))
const buff = toUint8Array(encoder)
this.conns.forEach((_, c) => {
send(this, c, buff)
})
}
constructor (readonly name: string) {
super({ gc: gcEnabled })
this.awareness = new Awareness(this)
this.awareness.setLocalState(null)
this.awareness.on('update', this.awarenessChangeHandler)
this.on('update', updateHandler)
}
}
/**
* Gets a Y.Doc by name, whether in memory or on disk
*
* @param {string} docId - the name of the Y.Doc to find or create
* @param {boolean} gc - whether to allow gc on the doc (applies only when created)
* @return {WSSharedDoc}
*/
export function getYDoc (
docId: string,
token: Token,
gc = true,
minio: MinioService,
initialContentId: string,
allowBind = true
): WSSharedDoc | undefined {
let doc = docs.get(docId)
if (doc === undefined && allowBind) {
doc = new WSSharedDoc(docId)
doc.gc = gc
docs.set(docId, doc)
void persistence.bindState(docId, doc, token, minio, initialContentId)
}
return doc
}
/**
* @param {any} conn
* @param {WSSharedDoc} doc
* @param {Uint8Array} message
*/
const messageListener = (conn: any, doc: WSSharedDoc, message: Uint8Array): void => {
try {
const encoder = createEncoder()
const decoder = createDecoder(message)
const messageType = readVarUint(decoder)
switch (messageType) {
case messageSync:
writeVarUint(encoder, messageSync)
readSyncMessage(decoder, encoder, doc, null)
// If the `encoder` only contains the type of reply message and no
// message, there is no need to send the message. When `encoder` only
// contains the type of reply, its length is 1.
if (length(encoder) > 1) {
send(doc, conn, toUint8Array(encoder))
}
break
case messageAwareness: {
applyAwarenessUpdate(doc.awareness, readVarUint8Array(decoder), conn)
break
}
}
} catch (err) {
console.error(err)
doc.emit('error', [err])
}
}
/**
* @param {WSSharedDoc} doc
* @param {any} conn
*/
const closeConn = (doc: WSSharedDoc, conn: any): void => {
if (doc.conns.has(conn)) {
/**
* @type {Set<number>}
*/
const controlledIds = doc.conns.get(conn)
doc.conns.delete(conn)
removeAwarenessStates(doc.awareness, Array.from(controlledIds?.ids?.values() ?? []), null)
if (doc.conns.size === 0 && persistence !== null) {
// if persisted, we store state and destroy ydocument
if (controlledIds !== undefined) {
void persistence.writeState(doc.name, doc, controlledIds?.token).then(() => {
docs.delete(doc.name)
doc.destroy()
})
}
}
}
conn.close()
}
/**
* @param {WSSharedDoc} doc
* @param {any} conn
* @param {Uint8Array} m
*/
const send = (doc: WSSharedDoc, conn: any, m: Uint8Array): void => {
if (conn.readyState !== wsReadyStateConnecting && conn.readyState !== wsReadyStateOpen) {
closeConn(doc, conn)
}
try {
conn.send(
m,
/** @param {any} err */ (err: any) => {
err != null && closeConn(doc, conn)
}
)
} catch (e) {
closeConn(doc, conn)
}
}
const pingTimeout = 30000
export function setupWSConnection (
conn: WebSocket,
req: any,
documentId: string,
token: Token,
minio: MinioService,
initialContentId: string,
gc = true
): void {
conn.binaryType = 'arraybuffer'
// get doc, initialize if it does not exist yet
const doc = getYDoc(documentId, token, gc, minio, initialContentId)
if (doc === undefined) {
conn.close()
return
}
doc.conns.set(conn, { ids: new Set(), token })
// listen and reply to events
conn.on('message', (message: ArrayBuffer) => messageListener(conn, doc, new Uint8Array(message)))
// Check if connection is still alive
let pongReceived = true
const pingInterval = setInterval(() => {
if (!pongReceived) {
if (doc.conns.has(conn)) {
closeConn(doc, conn)
}
clearInterval(pingInterval)
} else if (doc.conns.has(conn)) {
pongReceived = false
try {
conn.ping()
} catch (e) {
closeConn(doc, conn)
clearInterval(pingInterval)
}
}
}, pingTimeout)
conn.on('close', () => {
closeConn(doc, conn)
clearInterval(pingInterval)
})
conn.on('pong', () => {
pongReceived = true
})
// put the following in a variables in a block so the interval handlers don't keep in in
// scope
{
// send sync step 1
const encoder = createEncoder()
writeVarUint(encoder, messageSync)
writeSyncStep1(encoder, doc)
send(doc, conn, toUint8Array(encoder))
const awarenessStates = doc.awareness.getStates()
if (awarenessStates.size > 0) {
const encoder = createEncoder()
writeVarUint(encoder, messageAwareness)
writeVarUint8Array(encoder, encodeAwarenessUpdate(doc.awareness, Array.from(awarenessStates.keys())))
send(doc, conn, toUint8Array(encoder))
}
}
}
-10
View File
@@ -1,10 +0,0 @@
{
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib",
"esModuleInterop": true,
"types": ["node"]
}
}
-1
View File
@@ -1,7 +1,6 @@
#!/bin/bash
export ACCOUNTS_URL=http://localhost:3333
export COLLABORATOR_URL=ws://localhost:3078
export UPLOAD_URL=http://localhost:3333/files
export TRANSACTOR_URL=ws://localhost:3333
export ELASTIC_URL=http://elastic:9200
-2
View File
@@ -110,7 +110,6 @@
"@hcengineering/tracker-assets": "^0.6.0",
"@hcengineering/board-assets": "^0.6.10",
"@hcengineering/hr-assets": "^0.6.10",
"@hcengineering/document-assets": "^0.6.0",
"@hcengineering/bitrix-assets": "^0.6.0",
"@hcengineering/request-assets": "^0.6.0",
"@hcengineering/login": "^0.6.7",
@@ -136,7 +135,6 @@
"@hcengineering/tracker": "^0.6.11",
"@hcengineering/board": "^0.6.10",
"@hcengineering/hr": "^0.6.10",
"@hcengineering/document": "^0.6.0",
"@hcengineering/bitrix": "^0.6.41",
"@hcengineering/request": "^0.6.4",
"@hcengineering/support": "^0.6.0"
-3
View File
@@ -94,7 +94,6 @@ import { boardId } from '@hcengineering/board'
import { calendarId } from '@hcengineering/calendar'
import { chunterId } from '@hcengineering/chunter'
import { contactId } from '@hcengineering/contact'
import { documentId } from '@hcengineering/document'
import { gmailId } from '@hcengineering/gmail'
import { hrId } from '@hcengineering/hr'
import { inventoryId } from '@hcengineering/inventory'
@@ -126,7 +125,6 @@ import boardEn from '@hcengineering/board-assets/lang/en.json'
import calendarEn from '@hcengineering/calendar-assets/lang/en.json'
import chunterEn from '@hcengineering/chunter-assets/lang/en.json'
import contactEn from '@hcengineering/contact-assets/lang/en.json'
import documentEn from '@hcengineering/document-assets/lang/en.json'
import gmailEn from '@hcengineering/gmail-assets/lang/en.json'
import hrEn from '@hcengineering/hr-assets/lang/en.json'
import inventoryEn from '@hcengineering/inventory-assets/lang/en.json'
@@ -171,7 +169,6 @@ addStringsLoader(trackerId, async (lang: string) => trackerEn)
addStringsLoader(boardId, async (lang: string) => boardEn)
addStringsLoader(preferenceId, async (lang: string) => preferenceEn)
addStringsLoader(hrId, async (lang: string) => hrEn)
addStringsLoader(documentId, async (lang: string) => documentEn)
addStringsLoader(bitrixId, async (lang: string) => bitrixEn)
addStringsLoader(requestId, async (lang: string) => requestEn)
/**
-1
View File
@@ -1,6 +1,5 @@
{
"ACCOUNTS_URL":"http://localhost:3000",
"COLLABORATOR_URL": "ws://localhost:3078",
"UPLOAD_URL":"/files",
"REKONI_URL": "http://localhost:4004"
}
-1
View File
@@ -1,6 +1,5 @@
{
"ACCOUNTS_URL":"/account",
"COLLABORATOR_URL": "ws://localhost:3078",
"UPLOAD_URL":"/files",
"MODEL_VERSION": null
}
-26
View File
@@ -801,11 +801,6 @@
"projectFolder": "pods/account",
"shouldPublish": false
},
{
"packageName": "@hcengineering/pod-collaborator",
"projectFolder": "pods/collaborator",
"shouldPublish": false
},
{
"packageName": "@hcengineering/panel",
"projectFolder": "packages/panel",
@@ -1388,27 +1383,6 @@
"projectFolder": "server-plugins/hr-resources",
"shouldPublish": false
},
{
"packageName": "@hcengineering/document",
"projectFolder": "plugins/document",
"shouldPublish": false
},
{
"packageName": "@hcengineering/document-assets",
"projectFolder": "plugins/document-assets",
"shouldPublish": false
},
{
"packageName": "@hcengineering/document-resources",
"projectFolder": "plugins/document-resources",
"shouldPublish": false
},
{
"packageName": "@hcengineering/model-document",
"projectFolder": "models/document",
"shouldPublish": false
},
{
"packageName": "@hcengineering/apm",
"projectFolder": "tools/apm",
-1
View File
@@ -1,7 +1,6 @@
#!/bin/bash
export ACCOUNTS_URL=http://localhost:3333
export COLLABORATOR_URL=ws://localhost:3078
export UPLOAD_URL=http://localhost:3333/files
export TRANSACTOR_URL=ws://localhost:3333
export ELASTIC_URL=http://elastic:9200
-2
View File
@@ -136,7 +136,6 @@ export function start (
accountsUrl: string
uploadUrl: string
modelVersion: string
collaboratorUrl: string
rekoniUrl: string
telegramUrl: string
gmailUrl: string
@@ -177,7 +176,6 @@ export function start (
ACCOUNTS_URL: config.accountsUrl,
UPLOAD_URL: config.uploadUrl,
MODEL_VERSION: config.modelVersion,
COLLABORATOR_URL: config.collaboratorUrl,
REKONI_URL: config.rekoniUrl,
TELEGRAM_URL: config.telegramUrl,
GMAIL_URL: config.gmailUrl,
-7
View File
@@ -74,12 +74,6 @@ export function startFront (extraConfig?: Record<string, string>): void {
process.exit(1)
}
const collaboratorUrl = process.env.COLLABORATOR_URL
if (collaboratorUrl === undefined) {
console.error('please provide collaborator url')
process.exit(1)
}
const gmailUrl = process.env.GMAIL_URL
if (gmailUrl === undefined) {
console.error('please provide gmail url')
@@ -127,7 +121,6 @@ export function startFront (extraConfig?: Record<string, string>): void {
accountsUrl,
uploadUrl,
modelVersion,
collaboratorUrl,
gmailUrl,
telegramUrl,
rekoniUrl,
-14
View File
@@ -50,18 +50,6 @@ services:
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
- MODEL_ENABLED=*
collaborator:
image: hardcoreeng/collaborator
links:
- transactor
ports:
- 3079:3079
environment:
- COLLABORATOR_PORT=3079
- SECRET=secret
- MINIO_ENDPOINT=minio
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
front:
image: hardcoreeng/front
pull_policy: never
@@ -71,14 +59,12 @@ services:
- minio
- elastic
- transactor
- collaborator
ports:
- 8083:8083
environment:
- SERVER_PORT=8083
- SERVER_SECRET=secret
- ACCOUNTS_URL=http://localhost:3003
- COLLABORATOR_URL=ws://localhost:3079
- UPLOAD_URL=/files
- TRANSACTOR_URL=ws://localhost:3334
- ELASTIC_URL=http://elastic:9200