From 58d39f0cd6d866eb30331948c561712b798d2c7e Mon Sep 17 00:00:00 2001 From: Alexander Onnikov Date: Thu, 29 Feb 2024 15:32:39 +0700 Subject: [PATCH] UBERF-5642 Opensource wiki (#4818) Signed-off-by: Alexander Onnikov --- common/config/rush/pnpm-lock.yaml | 262 ++++++++++- dev/prod/package.json | 3 + dev/prod/src/platform.ts | 4 + dev/tool/package.json | 2 + dev/tool/src/__start.ts | 4 +- models/all/package.json | 4 +- models/all/src/index.ts | 15 + models/document/.eslintrc.js | 7 + models/document/.npmignore | 4 + models/document/config/rig.json | 5 + models/document/package.json | 55 +++ models/document/src/index.ts | 417 +++++++++++++++++ models/document/src/migration.ts | 229 ++++++++++ models/document/src/plugin.ts | 56 +++ models/document/tsconfig.json | 10 + models/server-document/.eslintrc.js | 7 + models/server-document/.npmignore | 4 + models/server-document/config/rig.json | 5 + models/server-document/package.json | 41 ++ models/server-document/src/index.ts | 34 ++ models/server-document/tsconfig.json | 10 + plugins/document-assets/.eslintrc.js | 7 + plugins/document-assets/assets/icons.svg | 50 ++ plugins/document-assets/config/rig.json | 5 + plugins/document-assets/jest.config.js | 7 + plugins/document-assets/lang/en.json | 63 +++ plugins/document-assets/lang/ru.json | 63 +++ plugins/document-assets/package.json | 39 ++ .../src/__tests__/lang.test.ts | 6 + plugins/document-assets/src/index.ts | 33 ++ plugins/document-assets/tsconfig.json | 11 + plugins/document-resources/.eslintrc.js | 4 + plugins/document-resources/config/rig.json | 5 + plugins/document-resources/jest.config.js | 7 + plugins/document-resources/package.json | 65 +++ plugins/document-resources/postcss.config.js | 5 + .../src/components/CreateDocument.svelte | 150 ++++++ .../src/components/CreateSnapshot.svelte | 50 ++ .../src/components/DocumentEditor.svelte | 89 ++++ .../src/components/DocumentIcon.svelte | 44 ++ .../src/components/DocumentItem.svelte | 33 ++ .../src/components/DocumentPresenter.svelte | 58 +++ .../src/components/DocumentSearchIcon.svelte | 37 ++ .../src/components/DocumentTitle.svelte | 99 ++++ .../components/DocumentToDoPresenter.svelte | 31 ++ .../src/components/Documents.svelte | 92 ++++ .../src/components/EditDoc.svelte | 426 ++++++++++++++++++ .../src/components/Move.svelte | 77 ++++ .../src/components/MyDocuments.svelte | 9 + .../src/components/NewDocumentHeader.svelte | 53 +++ .../NotificationDocumentPresenter.svelte | 27 ++ .../src/components/icons/Edit.svelte | 25 + .../components/navigator/DocHierarchy.svelte | 113 +++++ .../navigator/DocTreeElement.svelte | 116 +++++ .../navigator/TeamspaceSpacePresenter.svelte | 109 +++++ .../components/node-view/ToDoNodeView.svelte | 220 +++++++++ .../components/sidebar/BacklinkView.svelte | 49 ++ .../src/components/sidebar/Backlinks.svelte | 85 ++++ .../src/components/sidebar/History.svelte | 101 +++++ .../src/components/sidebar/HistoryView.svelte | 51 +++ .../teamspace/CreateTeamspace.svelte | 233 ++++++++++ .../teamspace/TeamspacePresenter.svelte | 46 ++ plugins/document-resources/src/index.ts | 161 +++++++ plugins/document-resources/src/plugin.ts | 95 ++++ plugins/document-resources/src/utils.ts | 139 ++++++ plugins/document-resources/svelte.config.js | 5 + plugins/document-resources/tsconfig.json | 9 + plugins/document/.eslintrc.js | 7 + plugins/document/.npmignore | 4 + plugins/document/config/rig.json | 4 + plugins/document/jest.config.js | 7 + plugins/document/package.json | 44 ++ plugins/document/src/index.ts | 133 ++++++ plugins/document/tsconfig.json | 10 + pods/server/package.json | 6 +- pods/server/src/server.ts | 6 + rush.json | 35 ++ .../document-resources/.eslintrc.js | 7 + server-plugins/document-resources/.npmignore | 4 + .../document-resources/.prettierignore | 1 + .../document-resources/config/rig.json | 4 + .../document-resources/jest.config.js | 7 + .../document-resources/package.json | 43 ++ .../document-resources/src/index.ts | 37 ++ .../document-resources/tsconfig.json | 10 + server-plugins/document/.eslintrc.js | 7 + server-plugins/document/.npmignore | 4 + server-plugins/document/.prettierignore | 1 + server-plugins/document/config/rig.json | 4 + server-plugins/document/jest.config.js | 7 + server-plugins/document/package.json | 41 ++ server-plugins/document/src/index.ts | 23 + server-plugins/document/tsconfig.json | 10 + 93 files changed, 4839 insertions(+), 7 deletions(-) create mode 100644 models/document/.eslintrc.js create mode 100644 models/document/.npmignore create mode 100644 models/document/config/rig.json create mode 100644 models/document/package.json create mode 100644 models/document/src/index.ts create mode 100644 models/document/src/migration.ts create mode 100644 models/document/src/plugin.ts create mode 100644 models/document/tsconfig.json create mode 100644 models/server-document/.eslintrc.js create mode 100644 models/server-document/.npmignore create mode 100644 models/server-document/config/rig.json create mode 100644 models/server-document/package.json create mode 100644 models/server-document/src/index.ts create mode 100644 models/server-document/tsconfig.json create mode 100644 plugins/document-assets/.eslintrc.js create mode 100644 plugins/document-assets/assets/icons.svg create mode 100644 plugins/document-assets/config/rig.json create mode 100644 plugins/document-assets/jest.config.js create mode 100644 plugins/document-assets/lang/en.json create mode 100644 plugins/document-assets/lang/ru.json create mode 100644 plugins/document-assets/package.json create mode 100644 plugins/document-assets/src/__tests__/lang.test.ts create mode 100644 plugins/document-assets/src/index.ts create mode 100644 plugins/document-assets/tsconfig.json create mode 100644 plugins/document-resources/.eslintrc.js create mode 100644 plugins/document-resources/config/rig.json create mode 100644 plugins/document-resources/jest.config.js create mode 100644 plugins/document-resources/package.json create mode 100644 plugins/document-resources/postcss.config.js create mode 100644 plugins/document-resources/src/components/CreateDocument.svelte create mode 100644 plugins/document-resources/src/components/CreateSnapshot.svelte create mode 100644 plugins/document-resources/src/components/DocumentEditor.svelte create mode 100644 plugins/document-resources/src/components/DocumentIcon.svelte create mode 100644 plugins/document-resources/src/components/DocumentItem.svelte create mode 100644 plugins/document-resources/src/components/DocumentPresenter.svelte create mode 100644 plugins/document-resources/src/components/DocumentSearchIcon.svelte create mode 100644 plugins/document-resources/src/components/DocumentTitle.svelte create mode 100644 plugins/document-resources/src/components/DocumentToDoPresenter.svelte create mode 100644 plugins/document-resources/src/components/Documents.svelte create mode 100644 plugins/document-resources/src/components/EditDoc.svelte create mode 100644 plugins/document-resources/src/components/Move.svelte create mode 100644 plugins/document-resources/src/components/MyDocuments.svelte create mode 100644 plugins/document-resources/src/components/NewDocumentHeader.svelte create mode 100644 plugins/document-resources/src/components/NotificationDocumentPresenter.svelte create mode 100644 plugins/document-resources/src/components/icons/Edit.svelte create mode 100644 plugins/document-resources/src/components/navigator/DocHierarchy.svelte create mode 100644 plugins/document-resources/src/components/navigator/DocTreeElement.svelte create mode 100644 plugins/document-resources/src/components/navigator/TeamspaceSpacePresenter.svelte create mode 100644 plugins/document-resources/src/components/node-view/ToDoNodeView.svelte create mode 100644 plugins/document-resources/src/components/sidebar/BacklinkView.svelte create mode 100644 plugins/document-resources/src/components/sidebar/Backlinks.svelte create mode 100644 plugins/document-resources/src/components/sidebar/History.svelte create mode 100644 plugins/document-resources/src/components/sidebar/HistoryView.svelte create mode 100644 plugins/document-resources/src/components/teamspace/CreateTeamspace.svelte create mode 100644 plugins/document-resources/src/components/teamspace/TeamspacePresenter.svelte create mode 100644 plugins/document-resources/src/index.ts create mode 100644 plugins/document-resources/src/plugin.ts create mode 100644 plugins/document-resources/src/utils.ts create mode 100644 plugins/document-resources/svelte.config.js create mode 100644 plugins/document-resources/tsconfig.json create mode 100644 plugins/document/.eslintrc.js create mode 100644 plugins/document/.npmignore create mode 100644 plugins/document/config/rig.json create mode 100644 plugins/document/jest.config.js create mode 100644 plugins/document/package.json create mode 100644 plugins/document/src/index.ts create mode 100644 plugins/document/tsconfig.json create mode 100644 server-plugins/document-resources/.eslintrc.js create mode 100644 server-plugins/document-resources/.npmignore create mode 100644 server-plugins/document-resources/.prettierignore create mode 100644 server-plugins/document-resources/config/rig.json create mode 100644 server-plugins/document-resources/jest.config.js create mode 100644 server-plugins/document-resources/package.json create mode 100644 server-plugins/document-resources/src/index.ts create mode 100644 server-plugins/document-resources/tsconfig.json create mode 100644 server-plugins/document/.eslintrc.js create mode 100644 server-plugins/document/.npmignore create mode 100644 server-plugins/document/.prettierignore create mode 100644 server-plugins/document/config/rig.json create mode 100644 server-plugins/document/jest.config.js create mode 100644 server-plugins/document/package.json create mode 100644 server-plugins/document/src/index.ts create mode 100644 server-plugins/document/tsconfig.json diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 513fa15a66..3ee64afc78 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -137,6 +137,15 @@ dependencies: '@rush-temp/devmodel-resources': specifier: file:./projects/devmodel-resources.tgz version: file:projects/devmodel-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2) + '@rush-temp/document': + specifier: file:./projects/document.tgz + version: file:projects/document.tgz(@types/node@20.11.19)(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2) + '@rush-temp/document-assets': + specifier: file:./projects/document-assets.tgz + version: file:projects/document-assets.tgz(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2) + '@rush-temp/document-resources': + specifier: file:./projects/document-resources.tgz + version: file:projects/document-resources.tgz(@tiptap/pm@2.2.3)(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2) '@rush-temp/elastic': specifier: file:./projects/elastic.tgz version: file:projects/elastic.tgz(@types/node@20.11.19)(esbuild@0.20.1)(svelte@4.2.11) @@ -245,6 +254,9 @@ dependencies: '@rush-temp/model-core': specifier: file:./projects/model-core.tgz version: file:projects/model-core.tgz(svelte@4.2.11) + '@rush-temp/model-document': + specifier: file:./projects/model-document.tgz + version: file:projects/model-document.tgz(svelte@4.2.11) '@rush-temp/model-gmail': specifier: file:./projects/model-gmail.tgz version: file:projects/model-gmail.tgz(svelte@4.2.11) @@ -296,6 +308,9 @@ dependencies: '@rush-temp/model-server-core': specifier: file:./projects/model-server-core.tgz version: file:projects/model-server-core.tgz(svelte@4.2.11) + '@rush-temp/model-server-document': + specifier: file:./projects/model-server-document.tgz + version: file:projects/model-server-document.tgz(svelte@4.2.11) '@rush-temp/model-server-gmail': specifier: file:./projects/model-server-gmail.tgz version: file:projects/model-server-gmail.tgz(svelte@4.2.11) @@ -506,6 +521,12 @@ dependencies: '@rush-temp/server-core': specifier: file:./projects/server-core.tgz version: file:projects/server-core.tgz(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2) + '@rush-temp/server-document': + specifier: file:./projects/server-document.tgz + version: file:projects/server-document.tgz(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2) + '@rush-temp/server-document-resources': + specifier: file:./projects/server-document-resources.tgz + version: file:projects/server-document-resources.tgz(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2) '@rush-temp/server-gmail': specifier: file:./projects/server-gmail.tgz version: file:projects/server-gmail.tgz(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2) @@ -1025,6 +1046,9 @@ dependencies: eslint: specifier: ^8.54.0 version: 8.56.0 + eslint-config-prettier: + specifier: ^8.8.0 + version: 8.10.0(eslint@8.56.0) eslint-config-standard-with-typescript: specifier: ^40.0.0 version: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) @@ -9290,6 +9314,15 @@ packages: eslint: 8.56.0 dev: false + /eslint-config-prettier@8.10.0(eslint@8.56.0): + resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.56.0 + dev: false + /eslint-config-standard-with-typescript@40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3): resolution: {integrity: sha512-GXUJcwIXiTQaS3H4etv8a1lejVVdZYaxZNz3g7vt6GoJosQqMTurbmSC4FVGyHiGT/d1TjFr3+47A3xsHhsG+Q==} peerDependencies: @@ -18136,6 +18169,118 @@ packages: - ts-node dev: false + file:projects/document-assets.tgz(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2): + resolution: {integrity: sha512-sAvhEkK/F32W0/18RBaZOCysXN31MrTnUiZgjzjUuxDxxjE/2w1FktW9fCk5skQ9/QFMfmymj23xIk2mfgDsBg==, tarball: file:projects/document-assets.tgz} + id: file:projects/document-assets.tgz + name: '@rush-temp/document-assets' + version: 0.0.0 + dependencies: + '@types/jest': 29.5.12 + '@types/node': 20.11.19 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.1(prettier@3.2.5)(svelte@4.2.11) + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - svelte + - ts-node + dev: false + + file:projects/document-resources.tgz(@tiptap/pm@2.2.3)(@types/node@20.11.19)(esbuild@0.20.1)(postcss-load-config@4.0.2)(postcss@8.4.35)(ts-node@10.9.2): + resolution: {integrity: sha512-bRzOCTKHO3ybxUKEvahwZTY9HzJAxrg3u9Y7gVc0jBpS3Y7rk03e18A+ixGRyFlaDORRLTqvQdVO3jGuCRPb/A==, tarball: file:projects/document-resources.tgz} + id: file:projects/document-resources.tgz + name: '@rush-temp/document-resources' + version: 0.0.0 + dependencies: + '@tiptap/core': 2.2.3(@tiptap/pm@2.2.3) + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + eslint-plugin-svelte: 2.35.1(eslint@8.56.0)(svelte@4.2.11)(ts-node@10.9.2) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.1(prettier@3.2.5)(svelte@4.2.11) + sass: 1.71.1 + slugify: 1.6.6 + svelte: 4.2.11 + svelte-check: 3.6.4(postcss-load-config@4.0.2)(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.11) + svelte-eslint-parser: 0.33.1(svelte@4.2.11) + svelte-loader: 3.1.9(svelte@4.2.11) + svelte-preprocess: 5.1.3(postcss-load-config@4.0.2)(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.11)(typescript@5.3.3) + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@tiptap/pm' + - '@types/node' + - babel-jest + - babel-plugin-macros + - coffeescript + - esbuild + - less + - node-notifier + - postcss + - postcss-load-config + - pug + - stylus + - sugarss + - supports-color + - ts-node + dev: false + + file:projects/document.tgz(@types/node@20.11.19)(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2): + resolution: {integrity: sha512-eiVo6MjtHd4x9VuU+G7osDtoO/N26CCwm5y8wudL5cLGXLAcDR8cg8CSA+BGwSz48CFUCqcnlWiCMPBg4DL9wQ==, tarball: file:projects/document.tgz} + id: file:projects/document.tgz + name: '@rush-temp/document' + version: 0.0.0 + dependencies: + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.1(prettier@3.2.5)(svelte@4.2.11) + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - svelte + - ts-node + dev: false + file:projects/elastic.tgz(@types/node@20.11.19)(esbuild@0.20.1)(svelte@4.2.11): resolution: {integrity: sha512-Wc3JhrVgrAwZNavtdaH6ynjqkUS+dx5n/AtYbt+slOcjhoOLiBWLR79sZ7/kk0ryil8znLcyU/VSzkcyUuJh9Q==, tarball: file:projects/elastic.tgz} id: file:projects/elastic.tgz @@ -19138,7 +19283,7 @@ packages: dev: false file:projects/model-all.tgz(svelte@4.2.11): - resolution: {integrity: sha512-dHsSkXsC7WkS9h8RlqjpSVF9TlqTA2UTiK5ehmxM3gJxpPFtrHrH8qD48u08TSh/nZJ2GlzinE5z6AvEuIHVsQ==, tarball: file:projects/model-all.tgz} + resolution: {integrity: sha512-/UebPPJADAYHCcMYwNRYXx9C07SalMNjMhoWd6MvoH+8P3XcKxB2zDdlM56UpqIydFxAMlTdr1ogX37bH/oZKg==, tarball: file:projects/model-all.tgz} id: file:projects/model-all.tgz name: '@rush-temp/model-all' version: 0.0.0 @@ -19311,6 +19456,27 @@ packages: - svelte dev: false + file:projects/model-document.tgz(svelte@4.2.11): + resolution: {integrity: sha512-JbmpZWS9k0cHwG3hMq7x5JONy0VXe3mI7wrgLMOOucwp2EQRY2VoGUo7r7braavPbdsWTPF/de7VyLuDUKCuJw==, tarball: file:projects/model-document.tgz} + id: file:projects/model-document.tgz + name: '@rush-temp/model-document' + version: 0.0.0 + dependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.1(prettier@3.2.5)(svelte@4.2.11) + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + - svelte + dev: false + file:projects/model-gmail.tgz(svelte@4.2.11): resolution: {integrity: sha512-fCmdls0TPCyCZe/Bk1W2WBgSd5eyKTr/SzKfkHKw+BPquzWkzvGZSVfzHtDKAIzqMIhEOg2KK8fplB790iM1ng==, tarball: file:projects/model-gmail.tgz} id: file:projects/model-gmail.tgz @@ -19669,6 +19835,28 @@ packages: - svelte dev: false + file:projects/model-server-document.tgz(svelte@4.2.11): + resolution: {integrity: sha512-e2TRkOKdHNrPZMlTW/N4BrdVrV1Gr58LJW9SYMJzCINnLobTM55x+iObbN8TIl8syvBmu2M5ZYhvggtq6ElAHg==, tarball: file:projects/model-server-document.tgz} + id: file:projects/model-server-document.tgz + name: '@rush-temp/model-server-document' + version: 0.0.0 + dependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-prettier: 8.10.0(eslint@8.56.0) + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.1(prettier@3.2.5)(svelte@4.2.11) + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + - svelte + dev: false + file:projects/model-server-gmail.tgz(svelte@4.2.11): resolution: {integrity: sha512-UUdnCHpYm0xpJGa7cnJq04tetZDHHNkzjz/gpMbw2J/KH36ARlIsHBZ62jHFUfTuHf8TVeki+eH+FKPe7x9NZQ==, tarball: file:projects/model-server-gmail.tgz} id: file:projects/model-server-gmail.tgz @@ -20798,7 +20986,7 @@ packages: dev: false file:projects/pod-server.tgz(svelte@4.2.11): - resolution: {integrity: sha512-t0dTTvzR0GNGvvEi8f/KAk65SeP43eYlOH5Bh1ObHU0zb7NAH8idybiYypKKkpRrZHydTDL/C1iFrjXTrqqVKQ==, tarball: file:projects/pod-server.tgz} + resolution: {integrity: sha512-rRrgSjbgcgoFqfaUlCyx/b0kG4FG+ULExDOMrCX9xF8i3rWRE4H96NhEYCLRfW7Tc/lRgb9z3CEJKRGwRyVkjQ==, tarball: file:projects/pod-server.tgz} id: file:projects/pod-server.tgz name: '@rush-temp/pod-server' version: 0.0.0 @@ -20947,7 +21135,7 @@ packages: dev: false file:projects/prod.tgz(bufferutil@4.0.8)(sass@1.71.1)(ts-node@10.9.2): - resolution: {integrity: sha512-sz8Xw/l82dtTDjeUD5fIOHpy9rjyTrbw1H7gh31h8nZxztMjPRZw9kRs9bzs9KidAPLnWEA/jL5T9j8QfaU01w==, tarball: file:projects/prod.tgz} + resolution: {integrity: sha512-F4zGBtEVGPF3SE5aMy+RgJG7Z+NisK8bAy1qnmb69SuI49W28YjL0dHh2tte+7lJsAyp0197awuzVL9cn6VbvA==, tarball: file:projects/prod.tgz} id: file:projects/prod.tgz name: '@rush-temp/prod' version: 0.0.0 @@ -21768,6 +21956,72 @@ packages: - ts-node dev: false + file:projects/server-document-resources.tgz(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2): + resolution: {integrity: sha512-AyHm5FwmRSY1cc1MftYP2pdwILDwe/F4PjUkScgJOZMAcNx3oKSxtvRI3tA95M9ajVWpDrIeR0s0qZxlfVknyw==, tarball: file:projects/server-document-resources.tgz} + id: file:projects/server-document-resources.tgz + name: '@rush-temp/server-document-resources' + version: 0.0.0 + dependencies: + '@types/jest': 29.5.12 + '@types/node': 20.11.19 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-prettier: 8.10.0(eslint@8.56.0) + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.1(prettier@3.2.5)(svelte@4.2.11) + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - svelte + - ts-node + dev: false + + file:projects/server-document.tgz(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2): + resolution: {integrity: sha512-BfqwjB0benM9hcjoYFCDB9LbHVaAO87egkiMdVvjfJp0qZrPN+bROdNvTk3fXxGedY0IVnEJB68tpLka7PzfRw==, tarball: file:projects/server-document.tgz} + id: file:projects/server-document.tgz + name: '@rush-temp/server-document' + version: 0.0.0 + dependencies: + '@types/jest': 29.5.12 + '@types/node': 20.11.19 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-prettier: 8.10.0(eslint@8.56.0) + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@15.7.0)(eslint-plugin-promise@6.1.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.1(prettier@3.2.5)(svelte@4.2.11) + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - svelte + - ts-node + dev: false + file:projects/server-gmail-resources.tgz(@types/node@20.11.19)(esbuild@0.20.1)(svelte@4.2.11)(ts-node@10.9.2): resolution: {integrity: sha512-u7orpqbtArpym2yzzDUzcG8jQm2v+lmeCHLR4ZgNDWLvi0isTpWDk0fb+8BPWZpoWEQppTIwksR9TLJnTo8eOA==, tarball: file:projects/server-gmail-resources.tgz} id: file:projects/server-gmail-resources.tgz @@ -23984,7 +24238,7 @@ packages: dev: false file:projects/tool.tgz(bufferutil@4.0.8)(svelte@4.2.11): - resolution: {integrity: sha512-u/v+y38hfzb8fBpMNT1IkihE0UA06lngEqh/bQWl6rMb4EMKOVc6V5N6YPq41mLIQvDnqMz4mzDsVRlq6c4HDQ==, tarball: file:projects/tool.tgz} + resolution: {integrity: sha512-s81ZA18JexSTNhl4N41DWrh6o3IcSWx2RVGJxa8lBpBNUCSHxNdIx9UYoTJ3fPPOODpF9CZFhPsdBka/WyCSew==, tarball: file:projects/tool.tgz} id: file:projects/tool.tgz name: '@rush-temp/tool' version: 0.0.0 diff --git a/dev/prod/package.json b/dev/prod/package.json index e80750f252..3e85389df8 100644 --- a/dev/prod/package.json +++ b/dev/prod/package.json @@ -176,6 +176,9 @@ "@hcengineering/server-view-resources": "^0.6.0", "@hcengineering/server-activity": "^0.6.0", "@hcengineering/server-activity-resources": "^0.6.0", + "@hcengineering/document": "^0.6.0", + "@hcengineering/document-assets": "^0.6.0", + "@hcengineering/document-resources": "^0.6.0", "@hcengineering/guest": "^0.6.0", "@hcengineering/guest-assets": "^0.6.0", "@hcengineering/guest-resources": "^0.6.0" diff --git a/dev/prod/src/platform.ts b/dev/prod/src/platform.ts index 6ae1c81b99..92e0297b5a 100644 --- a/dev/prod/src/platform.ts +++ b/dev/prod/src/platform.ts @@ -22,6 +22,7 @@ import calendar, { calendarId } from '@hcengineering/calendar' import { chunterId } from '@hcengineering/chunter' import client, { clientId } from '@hcengineering/client' import contactPlugin, { contactId } from '@hcengineering/contact' +import { documentId } from '@hcengineering/document' import gmail, { gmailId } from '@hcengineering/gmail' import guest, { guestId } from '@hcengineering/guest' import { hrId } from '@hcengineering/hr' @@ -53,6 +54,7 @@ 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/guest-assets' import '@hcengineering/hr-assets' @@ -132,6 +134,7 @@ function configureI18n(): void { addStringsLoader(trackerId, async (lang: string) => await import(`@hcengineering/tracker-assets/lang/${lang}.json`)) addStringsLoader(viewId, async (lang: string) => await import(`@hcengineering/view-assets/lang/${lang}.json`)) addStringsLoader(workbenchId, async (lang: string) => await import(`@hcengineering/workbench-assets/lang/${lang}.json`)) + addStringsLoader(documentId, async (lang: string) => await import(`@hcengineering/document-assets/lang/${lang}.json`)) addStringsLoader(guestId, async (lang: string) => await import(`@hcengineering/guest-assets/lang/${lang}.json`)) } @@ -208,6 +211,7 @@ export async function configurePlatform() { addLocation(bitrixId, () => import(/* webpackChunkName: "bitrix" */ '@hcengineering/bitrix-resources')) addLocation(requestId, () => import(/* webpackChunkName: "request" */ '@hcengineering/request-resources')) addLocation(supportId, () => import(/* webpackChunkName: "support" */ '@hcengineering/support-resources')) + addLocation(documentId, () => import(/* webpackChunkName: "document" */ '@hcengineering/document-resources')) addLocation(guestId, () => import(/* webpackChunkName: "guest" */ '@hcengineering/guest-resources')) setMetadata(client.metadata.FilterModel, true) diff --git a/dev/tool/package.json b/dev/tool/package.json index 433298ee5f..3ca6c1b1e4 100644 --- a/dev/tool/package.json +++ b/dev/tool/package.json @@ -88,6 +88,8 @@ "@hcengineering/server-contact": "^0.6.1", "@hcengineering/server-contact-resources": "^0.6.0", "@hcengineering/server-core": "^0.6.1", + "@hcengineering/server-document": "^0.6.0", + "@hcengineering/server-document-resources": "^0.6.0", "@hcengineering/server-gmail": "^0.6.0", "@hcengineering/server-gmail-resources": "^0.6.0", "@hcengineering/server-hr": "^0.6.0", diff --git a/dev/tool/src/__start.ts b/dev/tool/src/__start.ts index db386dd5ec..8eebfe1bae 100644 --- a/dev/tool/src/__start.ts +++ b/dev/tool/src/__start.ts @@ -28,7 +28,9 @@ import { serverCollaborationId } from '@hcengineering/server-collaboration' import { serverCalendarId } from '@hcengineering/server-calendar' import { serverChunterId } from '@hcengineering/server-chunter' import { serverContactId } from '@hcengineering/server-contact' +import { serverDocumentId } from '@hcengineering/server-document' import { serverGmailId } from '@hcengineering/server-gmail' +import { serverGuestId } from '@hcengineering/server-guest' import { serverHrId } from '@hcengineering/server-hr' import { serverInventoryId } from '@hcengineering/server-inventory' import { serverLeadId } from '@hcengineering/server-lead' @@ -41,7 +43,6 @@ import { serverTaskId } from '@hcengineering/server-task' import { serverTelegramId } from '@hcengineering/server-telegram' import { serverTrackerId } from '@hcengineering/server-tracker' import { serverViewId } from '@hcengineering/server-view' -import { serverGuestId } from '@hcengineering/server-guest' addLocation(serverActivityId, () => import('@hcengineering/server-activity-resources')) addLocation(serverAttachmentId, () => import('@hcengineering/server-attachment-resources')) @@ -62,6 +63,7 @@ addLocation(serverTelegramId, () => import('@hcengineering/server-telegram-resou addLocation(serverHrId, () => import('@hcengineering/server-hr-resources')) addLocation(serverRequestId, () => import('@hcengineering/server-request-resources')) addLocation(serverViewId, () => import('@hcengineering/server-view-resources')) +addLocation(serverDocumentId, () => import('@hcengineering/server-document-resources')) addLocation(serverGuestId, () => import('@hcengineering/server-guest-resources')) function prepareTools (): { diff --git a/models/all/package.json b/models/all/package.json index 88e30dcb98..4f0c047382 100644 --- a/models/all/package.json +++ b/models/all/package.json @@ -85,6 +85,8 @@ "@hcengineering/model-server-translate": "^0.6.0", "@hcengineering/model-support": "^0.6.0", "@hcengineering/model-guest": "^0.6.0", - "@hcengineering/model-server-guest": "^0.6.0" + "@hcengineering/model-server-guest": "^0.6.0", + "@hcengineering/model-document": "^0.6.0", + "@hcengineering/model-server-document": "^0.6.0" } } diff --git a/models/all/src/index.ts b/models/all/src/index.ts index 48207fdf60..8b3d70d4e5 100644 --- a/models/all/src/index.ts +++ b/models/all/src/index.ts @@ -24,6 +24,7 @@ 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' @@ -43,6 +44,7 @@ import { serverCalendarId, createModel as serverCalendarModel } from '@hcenginee import { serverChunterId, createModel as serverChunterModel } from '@hcengineering/model-server-chunter' import { serverContactId, createModel as serverContactModel } from '@hcengineering/model-server-contact' import { serverCoreId, createModel as serverCoreModel } from '@hcengineering/model-server-core' +import { serverDocumentId, createModel as serverDocumentModel } from '@hcengineering/model-server-document' import { serverGmailId, createModel as serverGmailModel } from '@hcengineering/model-server-gmail' import { serverHrId, createModel as serverHrModel } from '@hcengineering/model-server-hr' import { serverInventoryId, createModel as serverInventoryModel } from '@hcengineering/model-server-inventory' @@ -242,6 +244,18 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[ classFilter: defaultFilter } ], + [ + documentModel, + documentId, + { + label: document.string.ConfigLabel, + description: document.string.ConfigDescription, + enabled: true, + beta: true, + icon: document.icon.DocumentApplication, + classFilter: defaultFilter + } + ], [ boardModel, boardId, @@ -302,6 +316,7 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[ [serverActivityModel, serverActivityId], [serverTranslate, translateId], [serverOpenAI, openAIId], + [serverDocumentModel, serverDocumentId], [serverGuestModel, serverGuestId] ] diff --git a/models/document/.eslintrc.js b/models/document/.eslintrc.js new file mode 100644 index 0000000000..c1cf82cba0 --- /dev/null +++ b/models/document/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/model/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/models/document/.npmignore b/models/document/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/models/document/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/models/document/config/rig.json b/models/document/config/rig.json new file mode 100644 index 0000000000..2f6be36605 --- /dev/null +++ b/models/document/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "model" +} diff --git a/models/document/package.json b/models/document/package.json new file mode 100644 index 0000000000..9db5fd70e7 --- /dev/null +++ b/models/document/package.json @@ -0,0 +1,55 @@ +{ + "name": "@hcengineering/model-document", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "author": "Hardcore Engineering Inc.", + "template": "@hcengineering/model-package", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "_phase:build": "compile transpile src", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "prettier-plugin-svelte": "^3.1.0", + "typescript": "^5.3.3" + }, + "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-preference": "^0.6.0", + "@hcengineering/model-view": "^0.6.0", + "@hcengineering/model-guest": "^0.6.0", + "@hcengineering/model-presentation": "^0.6.0", + "@hcengineering/model-notification": "^0.6.0", + "@hcengineering/model-tracker": "^0.6.0", + "@hcengineering/model": "^0.6.7", + "@hcengineering/activity": "^0.6.0", + "@hcengineering/attachment": "^0.6.9", + "@hcengineering/setting": "^0.6.11", + "@hcengineering/core": "^0.6.28", + "@hcengineering/ui": "^0.6.11", + "@hcengineering/platform": "^0.6.9", + "@hcengineering/notification": "^0.6.16", + "@hcengineering/view": "^0.6.9", + "@hcengineering/tags": "^0.6.12", + "@hcengineering/time": "^0.6.0", + "@hcengineering/document": "^0.6.0", + "@hcengineering/document-resources": "^0.6.0" + } +} diff --git a/models/document/src/index.ts b/models/document/src/index.ts new file mode 100644 index 0000000000..12c2bd5d79 --- /dev/null +++ b/models/document/src/index.ts @@ -0,0 +1,417 @@ +// +// Copyright © 2022, 2023 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 activity from '@hcengineering/activity' +import type { Class, CollaborativeDoc, CollectionSize, Domain, Ref } from '@hcengineering/core' +import { IndexKind } from '@hcengineering/core' +import { + type Document, + type DocumentEmbedding, + type DocumentSnapshot, + type SavedDocument, + type Teamspace, + documentId +} from '@hcengineering/document' +import { + type Builder, + Collection, + Hidden, + Index, + Model, + Prop, + TypeNumber, + TypeRef, + TypeString, + UX, + TypeCollaborativeDoc, + TypeCollaborativeDocVersion +} from '@hcengineering/model' +import attachment, { TAttachment } from '@hcengineering/model-attachment' +import chunter from '@hcengineering/model-chunter' +import core, { TAttachedDoc, TSpace } from '@hcengineering/model-core' +import { createPublicLinkAction } from '@hcengineering/model-guest' +import { generateClassNotificationTypes } from '@hcengineering/model-notification' +import preference, { TPreference } from '@hcengineering/model-preference' +import presentation from '@hcengineering/model-presentation' +import tracker from '@hcengineering/model-tracker' +import view, { actionTemplates, createAction } from '@hcengineering/model-view' +import workbench from '@hcengineering/model-workbench' +import notification from '@hcengineering/notification' +import { type Asset } from '@hcengineering/platform' +import tags from '@hcengineering/tags' +import time from '@hcengineering/time' +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.DocumentEmbedding, attachment.class.Attachment) +@UX(document.string.Embedding) +export class TDocumentEmbedding extends TAttachment implements DocumentEmbedding { + declare attachedTo: Ref + declare attachedToClass: Ref> +} + +@Model(document.class.Document, core.class.AttachedDoc, DOMAIN_DOCUMENT) +@UX(document.string.Document, document.icon.Document, undefined, 'name') +export class TDocument extends TAttachedDoc implements Document { + @Prop(TypeRef(document.class.Document), document.string.ParentDocument) + declare attachedTo: Ref + + @Prop(TypeRef(core.class.Class), core.string.AttachedToClass) + @Hidden() + declare attachedToClass: Ref> + + @Prop(TypeString(), core.string.Collection) + @Hidden() + override collection: 'children' = 'children' + + @Prop(TypeString(), document.string.Name) + @Index(IndexKind.FullText) + name!: string + + @Prop(TypeCollaborativeDoc(), document.string.Document) + @Hidden() + content!: CollaborativeDoc + + @Prop(Collection(document.class.Document), document.string.ChildDocument) + children!: CollectionSize + + @Prop(Collection(document.class.DocumentEmbedding), document.string.Embeddings) + embeddings?: 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(chunter.class.Backlink), document.string.Backlinks) + @Hidden() + backlinks!: number + + @Prop(TypeString(), document.string.Icon) + @Hidden() + @Index(IndexKind.FullText) + icon?: Asset + + @Prop(TypeNumber(), document.string.Color) + @Hidden() + @Index(IndexKind.FullText) + color?: number +} + +@Model(document.class.DocumentSnapshot, core.class.AttachedDoc, DOMAIN_DOCUMENT) +@UX(document.string.Version) +export class TDocumentSnapshot extends TAttachedDoc implements DocumentSnapshot { + @Prop(TypeRef(document.class.Document), document.string.ParentDocument) + declare attachedTo: Ref + + @Prop(TypeRef(core.class.Class), core.string.AttachedToClass) + declare attachedToClass: Ref> + + @Prop(TypeString(), core.string.Collection) + @Hidden() + override collection: 'snapshots' = 'snapshots' + + @Prop(TypeString(), document.string.Name) + @Index(IndexKind.FullText) + name!: string + + @Prop(TypeCollaborativeDocVersion(), document.string.Document) + @Hidden() + content!: CollaborativeDoc +} + +@Model(document.class.SavedDocument, preference.class.Preference) +export class TSavedDocument extends TPreference implements SavedDocument { + @Prop(TypeRef(document.class.Document), document.string.SavedDocuments) + declare attachedTo: Ref +} + +@Model(document.class.Teamspace, core.class.Space) +@UX(document.string.Teamspace, document.icon.Teamspace, 'Teamspace', 'name') +export class TTeamspace extends TSpace implements Teamspace {} + +function defineTeamspace (builder: Builder): void { + builder.createModel(TTeamspace) + + // Navigator + + builder.mixin(document.class.Teamspace, core.class.Class, view.mixin.SpacePresenter, { + presenter: document.component.TeamspaceSpacePresenter + }) + + // Actions + + builder.mixin(document.class.Teamspace, core.class.Class, view.mixin.IgnoreActions, { + actions: [tracker.action.EditRelatedTargets] + }) + + createAction( + builder, + { + action: document.actionImpl.EditTeamspace, + label: document.string.EditTeamspace, + icon: view.icon.Edit, + input: 'focus', + category: document.category.Document, + target: document.class.Teamspace, + query: {}, + context: { + mode: ['context', 'browser'], + group: 'edit' + } + }, + document.action.EditTeamspace + ) + + createAction( + builder, + { + action: document.actionImpl.CreateDocument, + label: document.string.CreateDocument, + icon: document.icon.Add, + input: 'focus', + category: document.category.Document, + target: document.class.Teamspace, + inline: true, + context: { + mode: ['context', 'browser'], + application: document.app.Documents, + group: 'create' + } + }, + document.action.CreateDocument + ) + + createPublicLinkAction(builder, document.class.Document, document.action.PublicLink) +} + +function defineDocument (builder: Builder): void { + builder.createModel(TDocument, TDocumentSnapshot, TDocumentEmbedding, TSavedDocument) + + builder.mixin(document.class.Document, core.class.Class, time.mixin.ItemPresenter, { + presenter: document.component.DocumentToDoPresenter + }) + + 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.ObjectEditor, { + editor: document.component.EditDoc + }) + + builder.mixin(document.class.Document, core.class.Class, view.mixin.ObjectPanel, { + component: document.component.EditDoc + }) + + builder.mixin(document.class.Document, core.class.Class, view.mixin.ObjectPresenter, { + presenter: document.component.DocumentPresenter + }) + + builder.mixin(document.class.Document, core.class.Class, view.mixin.LinkProvider, { + encode: document.function.GetObjectLinkFragment + }) + + // Actions + + createAction(builder, { + ...actionTemplates.open, + actionProps: { + component: document.component.EditDoc + }, + target: document.class.Document, + context: { + mode: ['browser', 'context'], + group: 'create' + }, + override: [view.action.Open] + }) + + createAction(builder, { + ...actionTemplates.move, + action: view.actionImpl.ShowPopup, + actionProps: { + component: document.component.Move, + element: 'top', + fillProps: { + _object: 'value' + } + }, + target: document.class.Document, + context: { + mode: ['browser', 'context'], + group: 'tools' + } + }) + + createAction( + builder, + { + action: document.actionImpl.CreateChildDocument, + label: document.string.CreateDocument, + icon: document.icon.Add, + input: 'focus', + category: document.category.Document, + target: document.class.Document, + context: { + mode: ['context', 'browser'], + application: document.app.Documents, + group: 'create' + } + }, + document.action.CreateChildDocument + ) + + createAction( + builder, + { + action: view.actionImpl.CopyTextToClipboard, + actionProps: { + textProvider: document.function.GetDocumentLink + }, + label: document.string.CopyDocumentUrl, + icon: view.icon.CopyLink, + keyBinding: [], + input: 'focus', + category: document.category.Document, + target: document.class.Document, + context: { + mode: ['context', 'browser'], + application: document.app.Documents, + group: 'copy' + } + }, + document.action.CopyDocumentLink + ) + + // Notifications + + builder.mixin(document.class.Document, core.class.Class, activity.mixin.ActivityDoc, {}) + + builder.mixin(document.class.Document, core.class.Class, notification.mixin.ClassCollaborators, { + fields: ['createdBy', 'modifiedBy'] + }) + + builder.mixin(document.class.Document, core.class.Class, notification.mixin.NotificationObjectPresenter, { + presenter: document.component.NotificationDocumentPresenter + }) + + builder.mixin(document.class.Document, core.class.Class, view.mixin.IgnoreActions, { + actions: [view.action.Open, view.action.OpenInNewTab, tracker.action.NewRelatedIssue] + }) + + builder.createDoc( + notification.class.NotificationGroup, + core.space.Model, + { + label: document.string.DocumentApplication, + icon: document.icon.DocumentApplication, + objectClass: document.class.Document + }, + document.ids.DocumentNotificationGroup + ) + + builder.createDoc( + notification.class.NotificationType, + core.space.Model, + { + hidden: false, + generated: false, + allowedForAuthor: false, + label: document.string.Document, + group: document.ids.DocumentNotificationGroup, + field: 'content', + txClasses: [core.class.TxUpdateDoc], + objectClass: document.class.Document, + providers: { + [notification.providers.PlatformNotification]: true + } + }, + document.ids.ContentNotification + ) + + generateClassNotificationTypes( + builder, + document.class.Document, + document.ids.DocumentNotificationGroup, + [], + ['attachments', 'children', 'comments'] + ) + + // Search + + builder.createDoc( + presentation.class.ObjectSearchCategory, + core.space.Model, + { + title: document.string.Docs, + icon: document.icon.Document, + label: document.string.SearchDocument, + query: document.completion.DocumentQuery, + context: ['search', 'mention', 'spotlight'], + classToSearch: document.class.Document + }, + document.completion.DocumentQueryCategory + ) +} + +function defineApplication (builder: Builder): void { + builder.createDoc( + workbench.class.Application, + core.space.Model, + { + label: document.string.DocumentApplication, + icon: document.icon.DocumentApplication, + alias: documentId, + hidden: false, + locationResolver: document.resolver.Location, + navigatorModel: { + specials: [], + spaces: [ + { + id: 'teamspaces', + label: document.string.Teamspaces, + spaceClass: document.class.Teamspace, + addSpaceLabel: document.string.CreateTeamspace, + createComponent: document.component.CreateTeamspace, + visibleIf: document.function.IsTeamspaceVisible, + icon: document.icon.Library, + // intentionally left empty in order to make space presenter working + specials: [] + } + ] + }, + navHeaderComponent: document.component.NewDocumentHeader + }, + document.app.Documents + ) +} + +export function createModel (builder: Builder): void { + defineTeamspace(builder) + defineDocument(builder) + + defineApplication(builder) +} diff --git a/models/document/src/migration.ts b/models/document/src/migration.ts new file mode 100644 index 0000000000..59b4576ce0 --- /dev/null +++ b/models/document/src/migration.ts @@ -0,0 +1,229 @@ +// +// Copyright © 2022-2024 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { type Attachment } from '@hcengineering/attachment' +import { type Class, type Doc, type Ref, TxOperations, DOMAIN_TX, getCollaborativeDoc } from '@hcengineering/core' +import { type Document } from '@hcengineering/document' +import { + type MigrateOperation, + type MigrationClient, + type MigrationUpgradeClient, + tryMigrate +} from '@hcengineering/model' +import { DOMAIN_ATTACHMENT } from '@hcengineering/model-attachment' +import core from '@hcengineering/model-core' +import document, { documentId, DOMAIN_DOCUMENT } from './index' + +async function createSpace (tx: TxOperations): Promise { + 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 + ) + } +} + +async function migrateCollaborativeContent (client: MigrationClient): Promise { + const attachedFiles = await client.find(DOMAIN_ATTACHMENT, { + _class: 'document:class:CollaboratorDocument' as Ref>, + attachedToClass: document.class.Document + }) + + for (const attachment of attachedFiles) { + const collaborativeDoc = getCollaborativeDoc(attachment._id) + + await client.update( + DOMAIN_DOCUMENT, + { + _id: attachment.attachedTo, + _class: attachment.attachedToClass, + content: { + $exists: false + } + }, + { + $set: { + content: collaborativeDoc + } + } + ) + } + + // delete snapshots in old format + await client.deleteMany(DOMAIN_DOCUMENT, { + _class: 'document:class:DocumentSnapshot' as Ref>, + contentId: { $exists: true } + }) + + await client.update( + DOMAIN_DOCUMENT, + { + _class: document.class.Document, + snapshots: { $gt: 0 } + }, + { + $set: { + snapshots: 0 + } + } + ) + + // delete old snapshot transactions + await client.deleteMany(DOMAIN_TX, { + _class: core.class.TxCollectionCUD, + objectClass: document.class.Document, + collection: 'snapshots' + }) +} + +async function fixCollaborativeContentId (client: MigrationClient): Promise { + const documents = await client.find(DOMAIN_DOCUMENT, { + content: { $exists: true } + }) + + // there was a wrong migration that assigned incorrect collaborative doc id + for (const document of documents) { + if (!document.content.includes(':')) { + await client.update(DOMAIN_DOCUMENT, { _id: document._id }, { content: getCollaborativeDoc(document.content) }) + } + } +} + +async function migrateWrongDomainContent (client: MigrationClient): Promise { + // migrate content saved into wrong domain + const attachedFiles = await client.find(DOMAIN_DOCUMENT, { + _class: 'document:class:CollaboratorDocument' as Ref>, + attachedToClass: document.class.Document + }) + + for (const attachment of attachedFiles) { + const collaborativeDoc = getCollaborativeDoc(attachment._id) + + await client.update( + DOMAIN_DOCUMENT, + { + _id: attachment.attachedTo, + _class: attachment.attachedToClass, + content: { + $exists: false + } + }, + { + $set: { + content: collaborativeDoc + } + } + ) + } + + await client.move( + DOMAIN_DOCUMENT, + { + _class: 'document:class:CollaboratorDocument' as Ref>, + attachedToClass: document.class.Document + }, + DOMAIN_ATTACHMENT + ) +} + +async function setNoParent (client: MigrationClient): Promise { + await client.update( + DOMAIN_DOCUMENT, + { + _class: document.class.Document, + attachedTo: { $exists: false } + }, + { + $set: { + attachedTo: document.ids.NoParent, + attachedToClass: document.class.Document + } + } + ) + const docsWithParent = (await client.find(DOMAIN_DOCUMENT, { + _class: document.class.Document, + attachedTo: { $exists: true, $ne: document.ids.NoParent } + })) as Document[] + for (const doc of docsWithParent) { + const parent = await client.find(DOMAIN_DOCUMENT, { + _class: document.class.Document, + _id: doc.attachedTo + }) + if (parent.length === 0) continue + if (parent[0].space !== doc.space) { + await client.update( + DOMAIN_DOCUMENT, + { + _class: document.class.Document, + _id: doc._id + }, + { + $set: { + attachedTo: document.ids.NoParent + } + } + ) + } + } + + await client.update( + DOMAIN_DOCUMENT, + { + _class: document.class.Document, + attachedTo: '' + }, + { + $set: { + attachedTo: document.ids.NoParent + } + } + ) +} + +export const documentOperation: MigrateOperation = { + async migrate (client: MigrationClient): Promise { + await setNoParent(client) + await tryMigrate(client, documentId, [ + { + state: 'collaborativeContent', + func: migrateCollaborativeContent + }, + { + state: 'fixCollaborativeContentId', + func: fixCollaborativeContentId + }, + { + state: 'wrongDomainContent', + func: migrateWrongDomainContent + } + ]) + }, + + async upgrade (client: MigrationUpgradeClient): Promise { + const tx = new TxOperations(client, core.account.System) + await createSpace(tx) + } +} diff --git a/models/document/src/plugin.ts b/models/document/src/plugin.ts new file mode 100644 index 0000000000..bfc75bf9e6 --- /dev/null +++ b/models/document/src/plugin.ts @@ -0,0 +1,56 @@ +// +// Copyright © 2022, 2023 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 { type ObjectSearchCategory, type ObjectSearchFactory } from '@hcengineering/model-presentation' +import { type IntlString, mergeIds, type Resource } from '@hcengineering/platform' +import { type TagCategory } from '@hcengineering/tags' +import { type AnyComponent } from '@hcengineering/ui' +import { type Action, type ActionCategory, type ViewAction } from '@hcengineering/view' + +export default mergeIds(documentId, document, { + component: { + Documents: '' as AnyComponent, + DocumentPresenter: '' as AnyComponent, + NotificationDocumentPresenter: '' as AnyComponent, + TeamspaceSpacePresenter: '' as AnyComponent, + Move: '' as AnyComponent, + DocumentToDoPresenter: '' as AnyComponent + }, + completion: { + DocumentQuery: '' as Resource, + DocumentQueryCategory: '' as Ref + }, + actionImpl: { + CreateChildDocument: '' as ViewAction, + CreateDocument: '' as ViewAction, + EditTeamspace: '' as ViewAction + }, + action: { + PublicLink: '' as Ref> + }, + category: { + Document: '' as Ref, + Other: '' as Ref + }, + string: { + ConfigDescription: '' as IntlString, + ParentDocument: '' as IntlString, + ChildDocument: '' as IntlString + } +}) diff --git a/models/document/tsconfig.json b/models/document/tsconfig.json new file mode 100644 index 0000000000..9765b6086d --- /dev/null +++ b/models/document/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/model/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/models/server-document/.eslintrc.js b/models/server-document/.eslintrc.js new file mode 100644 index 0000000000..c1cf82cba0 --- /dev/null +++ b/models/server-document/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/model/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/models/server-document/.npmignore b/models/server-document/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/models/server-document/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/models/server-document/config/rig.json b/models/server-document/config/rig.json new file mode 100644 index 0000000000..2f6be36605 --- /dev/null +++ b/models/server-document/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "model" +} diff --git a/models/server-document/package.json b/models/server-document/package.json new file mode 100644 index 0000000000..b40c2547a4 --- /dev/null +++ b/models/server-document/package.json @@ -0,0 +1,41 @@ +{ + "name": "@hcengineering/model-server-document", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "author": "Hardcore Engineering Inc.", + "template": "@hcengineering/model-package", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "_phase:build": "compile transpile src", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "eslint-config-prettier": "^8.8.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "prettier-plugin-svelte": "^3.1.0", + "typescript": "^5.3.3" + }, + "dependencies": { + "@hcengineering/core": "^0.6.28", + "@hcengineering/model": "^0.6.7", + "@hcengineering/platform": "^0.6.9", + "@hcengineering/server-core": "^0.6.1", + "@hcengineering/server-notification": "^0.6.1", + "@hcengineering/model-core": "^0.6.0", + "@hcengineering/document": "^0.6.0", + "@hcengineering/server-document": "^0.6.0" + } +} diff --git a/models/server-document/src/index.ts b/models/server-document/src/index.ts new file mode 100644 index 0000000000..971165e197 --- /dev/null +++ b/models/server-document/src/index.ts @@ -0,0 +1,34 @@ +// +// Copyright © 2023 Hardcore Engineering Inc. +// +// + +import { type Builder } from '@hcengineering/model' + +import core from '@hcengineering/core' +import document from '@hcengineering/document' +import serverCore from '@hcengineering/server-core' +import serverDocument from '@hcengineering/server-document' +import serverNotification from '@hcengineering/server-notification' + +export { serverDocumentId } from '@hcengineering/server-document' + +export function createModel (builder: Builder): void { + builder.mixin(document.class.Document, core.class.Class, serverNotification.mixin.HTMLPresenter, { + presenter: serverDocument.function.DocumentHTMLPresenter + }) + + builder.mixin(document.class.Document, core.class.Class, serverNotification.mixin.TextPresenter, { + presenter: serverDocument.function.DocumentTextPresenter + }) + + builder.mixin(document.class.Document, core.class.Class, serverCore.mixin.SearchPresenter, { + searchConfig: { + iconConfig: { + component: document.component.DocumentSearchIcon, + props: ['icon', 'color'] + }, + title: 'name' + } + }) +} diff --git a/models/server-document/tsconfig.json b/models/server-document/tsconfig.json new file mode 100644 index 0000000000..9765b6086d --- /dev/null +++ b/models/server-document/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/model/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/plugins/document-assets/.eslintrc.js b/plugins/document-assets/.eslintrc.js new file mode 100644 index 0000000000..e73094bc7e --- /dev/null +++ b/plugins/document-assets/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/assets/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/plugins/document-assets/assets/icons.svg b/plugins/document-assets/assets/icons.svg new file mode 100644 index 0000000000..8dd7af1cca --- /dev/null +++ b/plugins/document-assets/assets/icons.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/document-assets/config/rig.json b/plugins/document-assets/config/rig.json new file mode 100644 index 0000000000..b75800b9b7 --- /dev/null +++ b/plugins/document-assets/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "assets" +} diff --git a/plugins/document-assets/jest.config.js b/plugins/document-assets/jest.config.js new file mode 100644 index 0000000000..2cfd408b67 --- /dev/null +++ b/plugins/document-assets/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/plugins/document-assets/lang/en.json b/plugins/document-assets/lang/en.json new file mode 100644 index 0000000000..5f9c524164 --- /dev/null +++ b/plugins/document-assets/lang/en.json @@ -0,0 +1,63 @@ +{ + "string": { + "CreateDocument": "Create a document", + "Documents": "Documents", + "CreateAnVersion": "Create new version", + "Document": "Document", + "DocumentNamePlaceholder": "Untitled", + "Name": "Name", + "Cancel": "Cancel", + "Version": "Version", + "SearchDocument": "Search document...", + "Snapshot": "Snapshot", + "ParentDocument": "Parent document", + "ChildDocument": "Child document", + "NoVersions": "No version's defined", + "DocumentApplication": "Documents", + "MyDocuments": "My documents", + "Library": "Library", + "Teamspace": "Teamspace", + "Teamspaces": "Teamspaces", + "Labels": "Labels", + "AddLabel": "Add label", + "Authors": "Authors", + "Backlinks": "Backlinks", + "History": "History", + "DescriptionPlaceholder": "type for details...", + "CreateTeamspace": "Create teamspace", + "EditTeamspace": "Edit teamspace", + "NewTeamspace": "New teamspace", + "TeamspaceTitle": "Teamspace title", + "TeamspaceTitlePlaceholder": "New teamspace", + "TeamspaceDescriptionPlaceholder": "Add description ...", + "ChooseIcon": "Choose icon", + "TeamspaceMembers": "Members", + "NoParentDocument": "No parent document", + "NoBacklinks": "No backlinks", + "NoHistory": "No previous history", + "Untitled": "Untitled", + + "Description": "Description", + + "CopyDocumentUrl": "Copy Document URL to clipboard", + + "ViewMode": "View", + "EditMode": "Edit", + "SuggestMode": "Suggest", + + "CompareTo": "Compare to...", + "Star": "Star", + "Unstar": "Unstar", + + "ConfigLabel": "Documents", + "ConfigDescription": "Extension for collaborative document editing", + + "UnassignToDo": "Unassign Todo", + "UnassignToDoConfirm": "Do you want to unassign Todo? The Todo will be removed from the assignee planning.", + "ReassignToDo": "Change Todo assignee", + "ReassignToDoConfirm": "Do you want to change Todo assignee? The Todo will be removed from the current assignee's planning.", + "Docs": "Docs", + "Icon": "Icon", + "Color": "Color" + } +} \ No newline at end of file diff --git a/plugins/document-assets/lang/ru.json b/plugins/document-assets/lang/ru.json new file mode 100644 index 0000000000..1b3195a5f8 --- /dev/null +++ b/plugins/document-assets/lang/ru.json @@ -0,0 +1,63 @@ +{ + "string": { + "CreateDocument": "Создать документ", + "Documents": "Документы", + "CreateAnVersion": "Создать новую версию", + "Document": "Документ", + "DocumentNamePlaceholder": "Без имени", + "Name": "Имя", + "Cancel": "Отмена", + "Version": "Версия", + "SearchDocument": "Найти документ...", + "Snapshot": "Снимок", + "ParentDocument": "Родительский документ", + "ChildDocument": "Дочерний документ", + "NoVersions": "Версии не определены", + "DocumentApplication": "Документы", + "MyDocuments": "Мои документы", + "Library": "Библиотека", + "Teamspace": "Пространство", + "Teamspaces": "Пространства", + "Labels": "Метки", + "AddLabel": "Добавить метку", + "Authors": "Авторы", + "Backlinks": "Упоминания", + "History": "История изменений", + "DescriptionPlaceholder": "введите для деталей...", + "CreateTeamspace": "Создать пространство", + "EditTeamspace": "Редактировать пространство", + "NewTeamspace": "Новое пространство", + "TeamspaceTitle": "Название пространства", + "TeamspaceTitlePlaceholder": "Новое пространство", + "TeamspaceDescriptionPlaceholder": "Добавьте описание ...", + "ChooseIcon": "Выбрать иконку", + "TeamspaceMembers": "Участники", + "NoParentDocument": "Нет родительского документа", + "NoBacklinks": "Нет упоминаний", + "NoHistory": "Нет истории изменений", + "Untitled": "Без имени", + + "Description": "Описание", + + "CopyDocumentUrl": "Копировать URL-адрес документа в буфер обмена", + + "ViewMode": "Просмотр", + "EditMode": "Редактирование", + "SuggestMode": "Комментирование", + + "CompareTo": "Сравнить с...", + "Star": "Добавить в закладки", + "Unstar": "Удалить из закладок", + + "ConfigLabel": "Документы", + "ConfigDescription": "Расширение по работе с текстовыми документами", + + "UnassignToDo": "Отменить назначение Todo", + "UnassignToDoConfirm": "Вы хотите отменить назначение Todo? Todo будет удалена из планирования исполнителя.", + "ReassignToDo": "Изменить исполнителя Todo", + "ReassignToDoConfirm": "Вы хотите изменить исполнителя Todo? Todo будет удалена из планирования текущего исполнителя.", + "Docs": "Документы", + "Icon": "Иконка", + "Color": "Цвет" + } +} \ No newline at end of file diff --git a/plugins/document-assets/package.json b/plugins/document-assets/package.json new file mode 100644 index 0000000000..972e323442 --- /dev/null +++ b/plugins/document-assets/package.json @@ -0,0 +1,39 @@ +{ + "name": "@hcengineering/document-assets", + "version": "0.6.0", + "main": "src/index.ts", + "author": "Hardcore Engineering Inc.", + "template": "@hcengineering/assets-package", + "scripts": { + "build": "compile", + "test": "jest --passWithNoTests --silent", + "build:docs": "", + "format": "format src", + "build:watch": "compile", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.4.0", + "eslint-plugin-promise": "^6.1.1", + "eslint": "^8.54.0", + "prettier": "^3.1.0", + "@types/node": "~20.11.16", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "prettier-plugin-svelte": "^3.1.0", + "typescript": "^5.3.3" + }, + "dependencies": { + "@hcengineering/platform": "^0.6.9", + "@hcengineering/document": "^0.6.0" + } +} diff --git a/plugins/document-assets/src/__tests__/lang.test.ts b/plugins/document-assets/src/__tests__/lang.test.ts new file mode 100644 index 0000000000..cf96c6dcf7 --- /dev/null +++ b/plugins/document-assets/src/__tests__/lang.test.ts @@ -0,0 +1,6 @@ +import { makeLocalesTest } from '@hcengineering/platform' + +it( + 'Locales are equale', + makeLocalesTest((lang) => import(`../../lang/${lang}.json`)) +) diff --git a/plugins/document-assets/src/index.ts b/plugins/document-assets/src/index.ts new file mode 100644 index 0000000000..be33a05e87 --- /dev/null +++ b/plugins/document-assets/src/index.ts @@ -0,0 +1,33 @@ +// +// Copyright © 2022, 2023 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 from '@hcengineering/document' +import { 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`, + Add: `${icons}#add`, + Blank: `${icons}#blank`, + Videofile: `${icons}#videofile`, + Library: `${icons}#library`, + Teamspace: `${icons}#teamspace`, + Backlinks: `${icons}#backlinks`, + History: `${icons}#history`, + Star: `${icons}#star`, + Starred: `${icons}#starred` +}) diff --git a/plugins/document-assets/tsconfig.json b/plugins/document-assets/tsconfig.json new file mode 100644 index 0000000000..4449c73536 --- /dev/null +++ b/plugins/document-assets/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/assets/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "types": ["node", "jest"], + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/plugins/document-resources/.eslintrc.js b/plugins/document-resources/.eslintrc.js new file mode 100644 index 0000000000..bb8fd7450d --- /dev/null +++ b/plugins/document-resources/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/ui/eslint.config.json'], + parserOptions: { tsconfigRootDir: __dirname } +} diff --git a/plugins/document-resources/config/rig.json b/plugins/document-resources/config/rig.json new file mode 100644 index 0000000000..bcad6f7c33 --- /dev/null +++ b/plugins/document-resources/config/rig.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig", + "rigProfile": "ui" +} diff --git a/plugins/document-resources/jest.config.js b/plugins/document-resources/jest.config.js new file mode 100644 index 0000000000..2cfd408b67 --- /dev/null +++ b/plugins/document-resources/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/plugins/document-resources/package.json b/plugins/document-resources/package.json new file mode 100644 index 0000000000..39802ee118 --- /dev/null +++ b/plugins/document-resources/package.json @@ -0,0 +1,65 @@ +{ + "name": "@hcengineering/document-resources", + "version": "0.6.0", + "main": "src/index.ts", + "author": "Hardcore Engineering Inc.", + "scripts": { + "build": "compile ui", + "build:docs": "api-extractor run --local", + "format": "format src", + "svelte-check": "do-svelte-check", + "_phase:svelte-check": "do-svelte-check", + "build:watch": "compile ui", + "_phase:build": "compile ui", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "svelte-loader": "^3.1.9", + "sass": "^1.53.0", + "svelte-preprocess": "^5.1.0", + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.4.0", + "eslint-plugin-promise": "^6.1.1", + "prettier-plugin-svelte": "^3.1.0", + "eslint": "^8.54.0", + "prettier": "^3.1.0", + "svelte-check": "^3.6.0", + "typescript": "^5.3.3", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "eslint-plugin-svelte": "^2.34.0", + "svelte-eslint-parser": "^0.33.1" + }, + "dependencies": { + "@hcengineering/platform": "^0.6.9", + "svelte": "^4.2.5", + "@hcengineering/ui": "^0.6.11", + "@hcengineering/setting": "^0.6.11", + "@hcengineering/presentation": "^0.6.2", + "@hcengineering/core": "^0.6.28", + "@hcengineering/view": "^0.6.9", + "@hcengineering/attachment-resources": "^0.6.0", + "@hcengineering/panel": "^0.6.15", + "@hcengineering/view-resources": "^0.6.0", + "@hcengineering/attachment": "^0.6.9", + "@hcengineering/notification": "^0.6.16", + "@hcengineering/login": "^0.6.8", + "@hcengineering/chunter": "^0.6.12", + "@hcengineering/contact": "^0.6.20", + "@hcengineering/contact-resources": "^0.6.0", + "@hcengineering/preference": "^0.6.9", + "@hcengineering/tags": "^0.6.12", + "@hcengineering/text-editor": "^0.6.0", + "@hcengineering/workbench": "^0.6.9", + "@hcengineering/document": "^0.6.0", + "@hcengineering/time": "^0.6.0", + "@tiptap/core": "^2.1.12", + "slugify": "^1.6.6" + } +} diff --git a/plugins/document-resources/postcss.config.js b/plugins/document-resources/postcss.config.js new file mode 100644 index 0000000000..88752c6cb0 --- /dev/null +++ b/plugins/document-resources/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: [ + require('autoprefixer') + ] +} diff --git a/plugins/document-resources/src/components/CreateDocument.svelte b/plugins/document-resources/src/components/CreateDocument.svelte new file mode 100644 index 0000000000..6777d73224 --- /dev/null +++ b/plugins/document-resources/src/components/CreateDocument.svelte @@ -0,0 +1,150 @@ + + + + + + { + dispatch('close') + }} + on:changeContent +> + + + + + +
+
+
+ +
+
diff --git a/plugins/document-resources/src/components/CreateSnapshot.svelte b/plugins/document-resources/src/components/CreateSnapshot.svelte new file mode 100644 index 0000000000..0d8e5cb288 --- /dev/null +++ b/plugins/document-resources/src/components/CreateSnapshot.svelte @@ -0,0 +1,50 @@ + + + + 0} on:close> +
+ +
+
diff --git a/plugins/document-resources/src/components/DocumentEditor.svelte b/plugins/document-resources/src/components/DocumentEditor.svelte new file mode 100644 index 0000000000..74825a07c3 --- /dev/null +++ b/plugins/document-resources/src/components/DocumentEditor.svelte @@ -0,0 +1,89 @@ + + + + diff --git a/plugins/document-resources/src/components/DocumentIcon.svelte b/plugins/document-resources/src/components/DocumentIcon.svelte new file mode 100644 index 0000000000..c4af3a7874 --- /dev/null +++ b/plugins/document-resources/src/components/DocumentIcon.svelte @@ -0,0 +1,44 @@ + + + + diff --git a/plugins/document-resources/src/components/DocumentItem.svelte b/plugins/document-resources/src/components/DocumentItem.svelte new file mode 100644 index 0000000000..3713829793 --- /dev/null +++ b/plugins/document-resources/src/components/DocumentItem.svelte @@ -0,0 +1,33 @@ + + + +
+
+ +
+ + {value.name} + +
diff --git a/plugins/document-resources/src/components/DocumentPresenter.svelte b/plugins/document-resources/src/components/DocumentPresenter.svelte new file mode 100644 index 0000000000..39d0e62212 --- /dev/null +++ b/plugins/document-resources/src/components/DocumentPresenter.svelte @@ -0,0 +1,58 @@ + + + +{#if value} + {#if inline} + + {:else} + +
+ {#if shouldShowAvatar} +
+ +
+ {/if} + + {value.name} + +
+
+ {/if} +{/if} diff --git a/plugins/document-resources/src/components/DocumentSearchIcon.svelte b/plugins/document-resources/src/components/DocumentSearchIcon.svelte new file mode 100644 index 0000000000..b7ceea0682 --- /dev/null +++ b/plugins/document-resources/src/components/DocumentSearchIcon.svelte @@ -0,0 +1,37 @@ + + + + diff --git a/plugins/document-resources/src/components/DocumentTitle.svelte b/plugins/document-resources/src/components/DocumentTitle.svelte new file mode 100644 index 0000000000..c24b13c1ce --- /dev/null +++ b/plugins/document-resources/src/components/DocumentTitle.svelte @@ -0,0 +1,99 @@ + + + +
+ +
+ + diff --git a/plugins/document-resources/src/components/DocumentToDoPresenter.svelte b/plugins/document-resources/src/components/DocumentToDoPresenter.svelte new file mode 100644 index 0000000000..d8b3d9e215 --- /dev/null +++ b/plugins/document-resources/src/components/DocumentToDoPresenter.svelte @@ -0,0 +1,31 @@ + + +{#if !withoutSpace} +
+
+{/if} +
+
+ +
+ {value.name} +
diff --git a/plugins/document-resources/src/components/Documents.svelte b/plugins/document-resources/src/components/Documents.svelte new file mode 100644 index 0000000000..b15cd1ac4a --- /dev/null +++ b/plugins/document-resources/src/components/Documents.svelte @@ -0,0 +1,92 @@ + + + + +
+
+
+ +
+
+
+
+ { + updateResultQuery(search, query) + }} + /> + +
+ +
+
+
+
+ + {#if loading} + + {:else if viewlet} + + {/if} +
diff --git a/plugins/document-resources/src/components/EditDoc.svelte b/plugins/document-resources/src/components/EditDoc.svelte new file mode 100644 index 0000000000..e82158bc57 --- /dev/null +++ b/plugins/document-resources/src/components/EditDoc.svelte @@ -0,0 +1,426 @@ + + + + + +{#if doc !== undefined} + dispatch('close')} + > + + + + + + + {#if !$restrictionStore.disableActions} +
+ + saveTitle(evt)} + on:keydown={(evt) => { + if (evt.key === 'Enter' || evt.key === 'ArrowDown') { + editor.focus('start') + } + }} + /> + + +
+
+
+ { + const heading = evt.detail + const element = window.document.getElementById(heading.id) + element?.scrollIntoView({ behavior: 'smooth', block: 'start' }) + }} + /> +
+
+ + {#key doc._id} + { + return await createEmbedding(file) + }} + on:headings={(evt) => { + headings = evt.detail + }} + on:open-document={async (event) => { + const doc = await client.findOne(event.detail._class, { _id: event.detail._id }) + if (doc != null) { + const location = await getObjectLinkFragment(client.getHierarchy(), doc, {}, view.component.EditDoc) + navigate(location) + } + }} + bind:this={editor} + /> + {/key} +
+ + + + {#if selectedAside === 'backlinks'} + + {:else if selectedAside === 'history'} + + {/if} + + + + + + +
+ +
+ + + + +
+ + + +
+ +
+
+
+ + +{/if} + + diff --git a/plugins/document-resources/src/components/Move.svelte b/plugins/document-resources/src/components/Move.svelte new file mode 100644 index 0000000000..d464455a48 --- /dev/null +++ b/plugins/document-resources/src/components/Move.svelte @@ -0,0 +1,77 @@ + + + + dispatch('close')} + on:changeContent +> +
+ + +
+
diff --git a/plugins/document-resources/src/components/MyDocuments.svelte b/plugins/document-resources/src/components/MyDocuments.svelte new file mode 100644 index 0000000000..3405511314 --- /dev/null +++ b/plugins/document-resources/src/components/MyDocuments.svelte @@ -0,0 +1,9 @@ + + + diff --git a/plugins/document-resources/src/components/NewDocumentHeader.svelte b/plugins/document-resources/src/components/NewDocumentHeader.svelte new file mode 100644 index 0000000000..d5cd006232 --- /dev/null +++ b/plugins/document-resources/src/components/NewDocumentHeader.svelte @@ -0,0 +1,53 @@ + + + +
+
diff --git a/plugins/document-resources/src/components/NotificationDocumentPresenter.svelte b/plugins/document-resources/src/components/NotificationDocumentPresenter.svelte new file mode 100644 index 0000000000..8412044461 --- /dev/null +++ b/plugins/document-resources/src/components/NotificationDocumentPresenter.svelte @@ -0,0 +1,27 @@ + + + +{#if value} +
+ + {value.name} + +
+{/if} diff --git a/plugins/document-resources/src/components/icons/Edit.svelte b/plugins/document-resources/src/components/icons/Edit.svelte new file mode 100644 index 0000000000..75f9e37912 --- /dev/null +++ b/plugins/document-resources/src/components/icons/Edit.svelte @@ -0,0 +1,25 @@ + + + + + + diff --git a/plugins/document-resources/src/components/navigator/DocHierarchy.svelte b/plugins/document-resources/src/components/navigator/DocHierarchy.svelte new file mode 100644 index 0000000000..7ed44024f0 --- /dev/null +++ b/plugins/document-resources/src/components/navigator/DocHierarchy.svelte @@ -0,0 +1,113 @@ + + + +{#each _documents as doc} + {@const desc = _descendants.get(doc._id) ?? []} + + {#if doc} + 0} + actions={getActions(doc)} + moreActions={() => getMoreActions(doc)} + {level} + on:click={() => { + handleDocumentSelected(doc._id) + }} + > + {#if desc.length} + + {/if} + + {/if} +{/each} diff --git a/plugins/document-resources/src/components/navigator/DocTreeElement.svelte b/plugins/document-resources/src/components/navigator/DocTreeElement.svelte new file mode 100644 index 0000000000..f2c147640f --- /dev/null +++ b/plugins/document-resources/src/components/navigator/DocTreeElement.svelte @@ -0,0 +1,116 @@ + + + + + +
0 ? level * 1.25 + 0.125 : 0.75}rem`} + on:click={() => { + selectDocument() + if (selected) { + collapsed = !collapsed + } + dispatch('click') + }} +> +
{ + if (parent) collapsed = !collapsed + }} + > + {#if parent}{/if} +
+ + {#if icon} +
+ +
+ {/if} + + {#if label} +
+ + {#each actions as action} + {#if action.icon} +
+ action.action({}, evt)} /> +
+ {/if} + {/each} +
+ +
+
+ +{#if parent && !collapsed} +
+{/if} diff --git a/plugins/document-resources/src/components/navigator/TeamspaceSpacePresenter.svelte b/plugins/document-resources/src/components/navigator/TeamspaceSpacePresenter.svelte new file mode 100644 index 0000000000..4199e4e111 --- /dev/null +++ b/plugins/document-resources/src/components/navigator/TeamspaceSpacePresenter.svelte @@ -0,0 +1,109 @@ + + + + 0} + actions={() => getActions(space)} + on:click={() => (collapsed = !collapsed)} +> + + diff --git a/plugins/document-resources/src/components/node-view/ToDoNodeView.svelte b/plugins/document-resources/src/components/node-view/ToDoNodeView.svelte new file mode 100644 index 0000000000..cebcff75c3 --- /dev/null +++ b/plugins/document-resources/src/components/node-view/ToDoNodeView.svelte @@ -0,0 +1,220 @@ + + + +
+
+ +
+ +
+ +
+ + +
+
+ + diff --git a/plugins/document-resources/src/components/sidebar/BacklinkView.svelte b/plugins/document-resources/src/components/sidebar/BacklinkView.svelte new file mode 100644 index 0000000000..c0bc638f7d --- /dev/null +++ b/plugins/document-resources/src/components/sidebar/BacklinkView.svelte @@ -0,0 +1,49 @@ + + + +
+
+
+ +
+
+ +
+
+
+ +
+
+ + diff --git a/plugins/document-resources/src/components/sidebar/Backlinks.svelte b/plugins/document-resources/src/components/sidebar/Backlinks.svelte new file mode 100644 index 0000000000..990d8600fb --- /dev/null +++ b/plugins/document-resources/src/components/sidebar/Backlinks.svelte @@ -0,0 +1,85 @@ + + + +
+
+
+
+ +
+ + {#if backlinks.length > 0} + + {#each backlinks as backlink} + + + + {/each} + + {:else} +
+
+
+
+ {/if} +
+ + diff --git a/plugins/document-resources/src/components/sidebar/History.svelte b/plugins/document-resources/src/components/sidebar/History.svelte new file mode 100644 index 0000000000..83b94b02f9 --- /dev/null +++ b/plugins/document-resources/src/components/sidebar/History.svelte @@ -0,0 +1,101 @@ + + + +
+
+
+ {#if !readonly} +
+ +
+ + {#if snapshots.length > 0} + + {#each snapshots as snapshot} + + + + {/each} + + {:else} +
+
+
+
+ {/if} +
+ + diff --git a/plugins/document-resources/src/components/sidebar/HistoryView.svelte b/plugins/document-resources/src/components/sidebar/HistoryView.svelte new file mode 100644 index 0000000000..e0a7bc8163 --- /dev/null +++ b/plugins/document-resources/src/components/sidebar/HistoryView.svelte @@ -0,0 +1,51 @@ + + + +
+
+
+ {value.name} +
+
+ +
+
+ +
+ + diff --git a/plugins/document-resources/src/components/teamspace/CreateTeamspace.svelte b/plugins/document-resources/src/components/teamspace/CreateTeamspace.svelte new file mode 100644 index 0000000000..824ceec549 --- /dev/null +++ b/plugins/document-resources/src/components/teamspace/CreateTeamspace.svelte @@ -0,0 +1,233 @@ + + + + 0 && !(members.length === 0 && isPrivate)} + accentHeader + width={'medium'} + gap={'gapV-6'} + onCancel={close} + on:changeContent +> +
+
+
+
+
+ { + if (isNew) { + color = isColorSelected ? color : getColorNumberByText(name) + } + }} + /> +
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+ +
+
+
+ (members = refs)} + kind={'regular'} + size={'large'} + /> +
+
+
diff --git a/plugins/document-resources/src/components/teamspace/TeamspacePresenter.svelte b/plugins/document-resources/src/components/teamspace/TeamspacePresenter.svelte new file mode 100644 index 0000000000..f3fa5d5440 --- /dev/null +++ b/plugins/document-resources/src/components/teamspace/TeamspacePresenter.svelte @@ -0,0 +1,46 @@ + + + +{#if value} +
+
+ +
+ + {value.name} + +
+{/if} diff --git a/plugins/document-resources/src/index.ts b/plugins/document-resources/src/index.ts new file mode 100644 index 0000000000..4165b49189 --- /dev/null +++ b/plugins/document-resources/src/index.ts @@ -0,0 +1,161 @@ +// +// Copyright © 2022, 2023 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 Class, + type Client, + type DocumentQuery, + type Ref, + type RelatedDocument, + type Space, + type WithLookup, + generateId, + getCurrentAccount +} from '@hcengineering/core' +import { type Document, type Teamspace } from '@hcengineering/document' +import { type Resources } from '@hcengineering/platform' +import preference from '@hcengineering/preference' +import { type ObjectSearchResult, getClient } from '@hcengineering/presentation' +import { showPopup } from '@hcengineering/ui' +import { openDoc } from '@hcengineering/view-resources' + +import CreateDocument from './components/CreateDocument.svelte' +import DocumentPresenter from './components/DocumentPresenter.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 CreateTeamspace from './components/teamspace/CreateTeamspace.svelte' +import TeamspaceSpacePresenter from './components/navigator/TeamspaceSpacePresenter.svelte' +import DocumentSearchIcon from './components/DocumentSearchIcon.svelte' +import NotificationDocumentPresenter from './components/NotificationDocumentPresenter.svelte' +import Move from './components/Move.svelte' +import DocumentToDoPresenter from './components/DocumentToDoPresenter.svelte' + +import document from './plugin' +import { createEmptyDocument, getDocumentLink, getDocumentUrl, resolveLocation } from './utils' + +const toObjectSearchResult = (e: WithLookup): ObjectSearchResult => ({ + doc: e, + title: e.name, + icon: document.icon.Document, + component: DocumentItem +}) + +async function queryDocument ( + _class: Ref>, + client: Client, + search: string, + filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] } +): Promise { + const q: DocumentQuery = { 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) + } + if (filter.nin !== undefined) { + q._id.$nin = filter.nin?.map((it) => it._id as Ref) + } + } + return (await client.findAll(_class, q, { limit: 200 })).map(toObjectSearchResult) +} + +async function createChildDocument (object: Document): Promise { + const id: Ref = generateId() + const space = object.space + const parent = object._id + + await _createDocument(id, space, parent) +} + +async function createDocument (space: Teamspace): Promise { + const id: Ref = generateId() + const parent = document.ids.NoParent + + await _createDocument(id, space._id, parent) +} + +async function _createDocument (id: Ref, space: Ref, parent: Ref): Promise { + const client = getClient() + + await createEmptyDocument(client, id, space, parent, {}) + + const doc = await client.findOne(document.class.Document, { _id: id }) + if (doc !== undefined) { + await openDoc(client.getHierarchy(), doc) + } +} + +async function editTeamspace (teamspace: Teamspace | undefined): Promise { + if (teamspace !== undefined) { + showPopup(CreateTeamspace, { teamspace }) + } +} + +export async function starDocument (doc: Document): Promise { + const client = getClient() + + await client.createDoc(document.class.SavedDocument, preference.space.Preference, { + attachedTo: doc._id + }) +} + +export async function unstarDocument (doc: Document): Promise { + const client = getClient() + + const current = await client.findOne(document.class.SavedDocument, { attachedTo: doc._id }) + if (current !== undefined) { + await client.remove(current) + } +} + +export default async (): Promise => ({ + component: { + CreateDocument, + CreateTeamspace, + DocumentPresenter, + Documents, + EditDoc, + TeamspaceSpacePresenter, + NewDocumentHeader, + MyDocuments, + DocumentSearchIcon, + NotificationDocumentPresenter, + Move, + DocumentToDoPresenter + }, + completion: { + DocumentQuery: async ( + client: Client, + query: string, + filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] } + ) => await queryDocument(document.class.Document, client, query, filter) + }, + actionImpl: { + CreateChildDocument: createChildDocument, + CreateDocument: createDocument, + EditTeamspace: editTeamspace + }, + function: { + GetDocumentLink: getDocumentUrl, + GetObjectLinkFragment: getDocumentLink, + IsTeamspaceVisible: async (space: Teamspace) => !space.private || space.members.includes(getCurrentAccount()._id) + }, + resolver: { + Location: resolveLocation + } +}) diff --git a/plugins/document-resources/src/plugin.ts b/plugins/document-resources/src/plugin.ts new file mode 100644 index 0000000000..e18bcb7803 --- /dev/null +++ b/plugins/document-resources/src/plugin.ts @@ -0,0 +1,95 @@ +// +// Copyright © 2022, 2023 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 } from '@hcengineering/core' +import document, { type Teamspace, documentId } from '@hcengineering/document' +import { type IntlString, type Resource, mergeIds } from '@hcengineering/platform' +import { type AnyComponent, type Location } from '@hcengineering/ui' + +export default mergeIds(documentId, document, { + component: { + EditDoc: '' as AnyComponent, + MyDocuments: '' as AnyComponent, + NewDocumentHeader: '' as AnyComponent, + Revision: '' as AnyComponent, + CreateTeamspace: '' as AnyComponent + }, + function: { + GetDocumentLink: '' as Resource<(doc: Doc, props: Record) => Promise>, + GetObjectLinkFragment: '' as Resource<(doc: Doc, props: Record) => Promise>, + IsTeamspaceVisible: '' as Resource<(space: Teamspace) => Promise> + }, + string: { + DocumentNamePlaceholder: '' as IntlString, + Name: '' as IntlString, + Cancel: '' as IntlString, + Documents: '' as IntlString, + Document: '' as IntlString, + SearchDocument: '' as IntlString, + Version: '' as IntlString, + Snapshot: '' as IntlString, + NoVersions: '' as IntlString, + NoBaseVersion: '' as IntlString, + DocumentApplication: '' as IntlString, + MyDocuments: '' as IntlString, + Library: '' as IntlString, + Teamspace: '' as IntlString, + Teamspaces: '' as IntlString, + Labels: '' as IntlString, + Authors: '' as IntlString, + Backlinks: '' as IntlString, + History: '' as IntlString, + SavedDocuments: '' as IntlString, + AddLabel: '' as IntlString, + NewTeamspace: '' as IntlString, + CreateTeamspace: '' as IntlString, + EditTeamspace: '' as IntlString, + TeamspaceTitle: '' as IntlString, + TeamspaceMembers: '' as IntlString, + TeamspaceTitlePlaceholder: '' as IntlString, + TeamspaceDescriptionPlaceholder: '' as IntlString, + ChooseIcon: '' as IntlString, + NoParentDocument: '' as IntlString, + NoBacklinks: '' as IntlString, + NoHistory: '' as IntlString, + Untitled: '' as IntlString, + + Description: '' as IntlString, + DescriptionPlaceholder: '' as IntlString, + + Star: '' as IntlString, + Unstar: '' as IntlString, + CopyDocumentUrl: '' as IntlString, + + ViewMode: '' as IntlString, + EditMode: '' as IntlString, + SuggestMode: '' as IntlString, + + ChildDocuments: '' as IntlString, + Embedding: '' as IntlString, + Embeddings: '' as IntlString, + + CompareTo: '' as IntlString, + + UnassignToDo: '' as IntlString, + UnassignToDoConfirm: '' as IntlString, + ReassignToDo: '' as IntlString, + ReassignToDoConfirm: '' as IntlString, + + Docs: '' as IntlString, + Color: '' as IntlString, + Icon: '' as IntlString + } +}) diff --git a/plugins/document-resources/src/utils.ts b/plugins/document-resources/src/utils.ts new file mode 100644 index 0000000000..d2adff0d4a --- /dev/null +++ b/plugins/document-resources/src/utils.ts @@ -0,0 +1,139 @@ +// +// Copyright © 2023, 2024 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { + type AttachedData, + type Ref, + type TxOperations, + getCollaborativeDoc, + getCollaborativeDocId +} from '@hcengineering/core' +import { type Document, type Teamspace, documentId } from '@hcengineering/document' +import { getMetadata, translate } from '@hcengineering/platform' +import presentation, { getClient } from '@hcengineering/presentation' +import { type Location, type ResolvedLocation, getCurrentResolvedLocation, getPanelURI } from '@hcengineering/ui' +import { workbenchId } from '@hcengineering/workbench' +import slugify from 'slugify' + +import document from './plugin' + +export async function createEmptyDocument ( + client: TxOperations, + id: Ref, + space: Ref, + parent: Ref, + data: Partial, 'name' | 'icon' | 'color'>> = {} +): Promise { + const name = await translate(document.string.Untitled, {}) + const collaborativeDocId = getCollaborativeDocId(id, 'content') + + const object: AttachedData = { + name, + content: getCollaborativeDoc(collaborativeDocId), + attachments: 0, + children: 0, + embeddings: 0, + labels: 0, + comments: 0, + backlinks: 0, + ...data + } + + await client.addCollection( + document.class.Document, + space, + parent ?? document.ids.NoParent, + document.class.Document, + 'children', + object, + id + ) +} + +export async function resolveLocation (loc: Location): Promise { + if (loc.path[2] !== documentId) { + return undefined + } + + const shortLink = loc.path[3] + const id = parseDocumentId(shortLink) + + if (id !== undefined) { + return await generateLocation(loc, id) + } + + return undefined +} + +export async function generateLocation (loc: Location, id: Ref): Promise { + const client = getClient() + + const doc = await client.findOne(document.class.Document, { _id: id }) + if (doc === undefined) { + console.error(`Could not find document ${id}.`) + return undefined + } + + const appComponent = loc.path[0] ?? '' + const workspace = loc.path[1] ?? '' + + return { + loc: { + path: [appComponent, workspace, documentId, doc.space], + fragment: getPanelURI(document.component.EditDoc, doc._id, doc._class, 'content') + }, + defaultLocation: { + path: [appComponent, workspace, documentId], + fragment: getPanelURI(document.component.EditDoc, doc._id, doc._class, 'content') + } + } +} + +export function getDocumentIdFromFragment (fragment: string): Ref { + return fragment as Ref +} + +export function getDocumentUrl (doc: Document): string { + const id = getDocumentId(doc) + + const location = getCurrentResolvedLocation() + const frontUrl = getMetadata(presentation.metadata.FrontUrl) + const protocolAndHost = frontUrl ?? `${window.location.protocol}//${window.location.host}` + return `${protocolAndHost}/${workbenchId}/${location.path[1]}/${documentId}/${id}` +} + +export function getDocumentLink (doc: Document): Location { + const loc = getCurrentResolvedLocation() + loc.path.length = 2 + loc.fragment = undefined + loc.query = undefined + loc.path[2] = documentId + loc.path[3] = getDocumentId(doc) + + return loc +} + +function getDocumentId (doc: Document): string { + const slug = slugify(doc.name, { lower: true }) + return `${slug}-${doc._id}` +} + +function parseDocumentId (shortLink: string): Ref | undefined { + const parts = shortLink.split('-') + if (parts.length > 1) { + return parts[parts.length - 1] as Ref + } + return undefined +} diff --git a/plugins/document-resources/svelte.config.js b/plugins/document-resources/svelte.config.js new file mode 100644 index 0000000000..944a06f73e --- /dev/null +++ b/plugins/document-resources/svelte.config.js @@ -0,0 +1,5 @@ +const sveltePreprocess = require('svelte-preprocess') + +module.exports = { + preprocess: sveltePreprocess() +}; \ No newline at end of file diff --git a/plugins/document-resources/tsconfig.json b/plugins/document-resources/tsconfig.json new file mode 100644 index 0000000000..fb6ccb2d18 --- /dev/null +++ b/plugins/document-resources/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/ui/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types" + } +} \ No newline at end of file diff --git a/plugins/document/.eslintrc.js b/plugins/document/.eslintrc.js new file mode 100644 index 0000000000..72235dc283 --- /dev/null +++ b/plugins/document/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/plugins/document/.npmignore b/plugins/document/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/plugins/document/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/plugins/document/config/rig.json b/plugins/document/config/rig.json new file mode 100644 index 0000000000..0110930f55 --- /dev/null +++ b/plugins/document/config/rig.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig" +} diff --git a/plugins/document/jest.config.js b/plugins/document/jest.config.js new file mode 100644 index 0000000000..2cfd408b67 --- /dev/null +++ b/plugins/document/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/plugins/document/package.json b/plugins/document/package.json new file mode 100644 index 0000000000..b9bf1e1288 --- /dev/null +++ b/plugins/document/package.json @@ -0,0 +1,44 @@ +{ + "name": "@hcengineering/document", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "author": "Hardcore Engineering Inc.", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "test": "jest --passWithNoTests --silent", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "typescript": "^5.3.3", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "prettier-plugin-svelte": "^3.1.0" + }, + "dependencies": { + "@hcengineering/platform": "^0.6.9", + "@hcengineering/ui": "^0.6.11", + "@hcengineering/core": "^0.6.28", + "@hcengineering/view": "^0.6.9", + "@hcengineering/contact": "^0.6.20", + "@hcengineering/notification": "^0.6.16", + "@hcengineering/attachment": "^0.6.9", + "@hcengineering/preference": "^0.6.9" + } +} diff --git a/plugins/document/src/index.ts b/plugins/document/src/index.ts new file mode 100644 index 0000000000..72d9b38cab --- /dev/null +++ b/plugins/document/src/index.ts @@ -0,0 +1,133 @@ +// +// Copyright © 2022, 2023 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 { AttachedDoc, Class, CollaborativeDoc, Doc, Ref, Space } from '@hcengineering/core' +import type { Asset, Plugin, Resource } from '@hcengineering/platform' +import { Preference } from '@hcengineering/preference' +import { IntlString, plugin } from '@hcengineering/platform' +import type { AnyComponent, Location, ResolvedLocation } from '@hcengineering/ui' +import { Action, IconProps } from '@hcengineering/view' +import { NotificationGroup, NotificationType } from '@hcengineering/notification' + +/** + * @public + */ +export interface Teamspace extends Space, IconProps {} + +/** + * @public + */ +export interface Document extends AttachedDoc, IconProps { + attachedTo: Ref + + name: string + content: CollaborativeDoc + + snapshots?: number + + attachments?: number + children?: number + comments?: number + embeddings?: number + labels?: number + backlinks?: number +} + +/** + * @public + */ +export interface DocumentSnapshot extends AttachedDoc { + attachedTo: Ref + name: string + content: CollaborativeDoc +} + +/** + * @public + */ +export interface SavedDocument extends Preference { + attachedTo: Ref +} + +/** + * @public + */ +export interface DocumentEmbedding extends Attachment { + attachedTo: Ref + attachedToClass: Ref> +} + +/** + * @public + */ +export const documentId = 'document' as Plugin + +/** + * @public + */ +const documentPlugin = plugin(documentId, { + class: { + Document: '' as Ref>, + DocumentSnapshot: '' as Ref>, + DocumentEmbedding: '' as Ref>, + SavedDocument: '' as Ref>, + Teamspace: '' as Ref> + }, + component: { + CreateDocument: '' as AnyComponent, + DocumentSearchIcon: '' as AnyComponent + }, + action: { + CopyDocumentLink: '' as Ref>, + CreateChildDocument: '' as Ref, + CreateDocument: '' as Ref, + EditTeamspace: '' as Ref + }, + icon: { + DocumentApplication: '' as Asset, + NewDocument: '' as Asset, + Document: '' as Asset, + Add: '' as Asset, + Blank: '' as Asset, + Videofile: '' as Asset, + Library: '' as Asset, + Teamspace: '' as Asset, + Backlinks: '' as Asset, + History: '' as Asset, + Star: '' as Asset, + Starred: '' as Asset + }, + space: { + Documents: '' as Ref + }, + app: { + Documents: '' as Ref + }, + resolver: { + Location: '' as Resource<(loc: Location) => Promise> + }, + string: { + ConfigLabel: '' as IntlString, + CreateDocument: '' as IntlString + }, + ids: { + NoParent: '' as Ref, + DocumentNotificationGroup: '' as Ref, + ContentNotification: '' as Ref + } +}) + +export default documentPlugin diff --git a/plugins/document/tsconfig.json b/plugins/document/tsconfig.json new file mode 100644 index 0000000000..59e4fd4297 --- /dev/null +++ b/plugins/document/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/pods/server/package.json b/pods/server/package.json index d040366460..bc36bb2119 100644 --- a/pods/server/package.json +++ b/pods/server/package.json @@ -96,6 +96,8 @@ "@hcengineering/server-view-resources": "^0.6.0", "@hcengineering/server-activity": "^0.6.0", "@hcengineering/server-activity-resources": "^0.6.0", + "@hcengineering/server-document": "^0.6.0", + "@hcengineering/server-document-resources": "^0.6.0", "@hcengineering/server-guest": "^0.6.0", "@hcengineering/server-guest-resources": "^0.6.0", "@hcengineering/server-token": "^0.6.7", @@ -128,6 +130,7 @@ "@hcengineering/hr-assets": "^0.6.12", "@hcengineering/bitrix-assets": "^0.6.0", "@hcengineering/request-assets": "^0.6.0", + "@hcengineering/document-assets": "^0.6.0", "@hcengineering/login": "^0.6.8", "@hcengineering/view": "^0.6.9", "@hcengineering/task": "^0.6.13", @@ -152,6 +155,7 @@ "@hcengineering/hr": "^0.6.12", "@hcengineering/bitrix": "^0.6.44", "@hcengineering/request": "^0.6.6", - "@hcengineering/support": "^0.6.1" + "@hcengineering/support": "^0.6.1", + "@hcengineering/document": "^0.6.0" } } diff --git a/pods/server/src/server.ts b/pods/server/src/server.ts index 0928993049..54379e240e 100644 --- a/pods/server/src/server.ts +++ b/pods/server/src/server.ts @@ -81,6 +81,7 @@ import { type Token } from '@hcengineering/server-token' import { serverTrackerId } from '@hcengineering/server-tracker' import { serverViewId } from '@hcengineering/server-view' import { serverActivityId } from '@hcengineering/server-activity' +import { serverDocumentId } from '@hcengineering/server-document' import { serverGuestId } from '@hcengineering/server-guest' import { type BroadcastCall, @@ -98,6 +99,7 @@ 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' @@ -128,6 +130,7 @@ 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' @@ -173,6 +176,8 @@ addStringsLoader(preferenceId, async (lang: string) => preferenceEn) addStringsLoader(hrId, async (lang: string) => hrEn) addStringsLoader(bitrixId, async (lang: string) => bitrixEn) addStringsLoader(requestId, async (lang: string) => requestEn) +addStringsLoader(documentId, async (lang: string) => documentEn) + /** * @public */ @@ -215,6 +220,7 @@ export function start ( addLocation(serverActivityId, () => import('@hcengineering/server-activity-resources')) addLocation(serverGuestId, () => import('@hcengineering/server-guest-resources')) addLocation(openAIId, () => Promise.resolve({ default: openAIPluginImpl })) + addLocation(serverDocumentId, () => import('@hcengineering/server-document-resources')) const middlewares: MiddlewareCreator[] = [ ModifiedMiddleware.create, diff --git a/rush.json b/rush.json index 64a8636167..5d3a3dd845 100644 --- a/rush.json +++ b/rush.json @@ -1617,5 +1617,40 @@ "projectFolder": "models/server-time", "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/server-document", + "projectFolder": "server-plugins/document", + "shouldPublish": false + }, + { + "packageName": "@hcengineering/server-document-resources", + "projectFolder": "server-plugins/document-resources", + "shouldPublish": false + }, + { + "packageName": "@hcengineering/model-server-document", + "projectFolder": "models/server-document", + "shouldPublish": false + } ] } diff --git a/server-plugins/document-resources/.eslintrc.js b/server-plugins/document-resources/.eslintrc.js new file mode 100644 index 0000000000..72235dc283 --- /dev/null +++ b/server-plugins/document-resources/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/server-plugins/document-resources/.npmignore b/server-plugins/document-resources/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/server-plugins/document-resources/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/server-plugins/document-resources/.prettierignore b/server-plugins/document-resources/.prettierignore new file mode 100644 index 0000000000..21c8f7d149 --- /dev/null +++ b/server-plugins/document-resources/.prettierignore @@ -0,0 +1 @@ +tsdoc-metadata.json \ No newline at end of file diff --git a/server-plugins/document-resources/config/rig.json b/server-plugins/document-resources/config/rig.json new file mode 100644 index 0000000000..0110930f55 --- /dev/null +++ b/server-plugins/document-resources/config/rig.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig" +} diff --git a/server-plugins/document-resources/jest.config.js b/server-plugins/document-resources/jest.config.js new file mode 100644 index 0000000000..2cfd408b67 --- /dev/null +++ b/server-plugins/document-resources/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/server-plugins/document-resources/package.json b/server-plugins/document-resources/package.json new file mode 100644 index 0000000000..f05a91ae5e --- /dev/null +++ b/server-plugins/document-resources/package.json @@ -0,0 +1,43 @@ +{ + "name": "@hcengineering/server-document-resources", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "author": "Hardcore Engineering Inc.", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "test": "jest --passWithNoTests --silent", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "eslint-config-prettier": "^8.8.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "typescript": "^5.3.3", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "@types/node": "~20.11.16", + "prettier-plugin-svelte": "^3.1.0" + }, + "dependencies": { + "@hcengineering/core": "^0.6.28", + "@hcengineering/platform": "^0.6.9", + "@hcengineering/workbench": "^0.6.9", + "@hcengineering/server-core": "^0.6.1", + "@hcengineering/document": "^0.6.0" + } +} diff --git a/server-plugins/document-resources/src/index.ts b/server-plugins/document-resources/src/index.ts new file mode 100644 index 0000000000..1336d1ed02 --- /dev/null +++ b/server-plugins/document-resources/src/index.ts @@ -0,0 +1,37 @@ +// +// Copyright © 2024 Hardcore Engineering Inc. +// +// + +import { Doc, concatLink } from '@hcengineering/core' +import { Document, documentId } from '@hcengineering/document' +import { getMetadata } from '@hcengineering/platform' +import { workbenchId } from '@hcengineering/workbench' +import serverCore, { TriggerControl } from '@hcengineering/server-core' + +/** + * @public + */ +export async function documentHTMLPresenter (doc: Doc, control: TriggerControl): Promise { + const document = doc as Document + const front = getMetadata(serverCore.metadata.FrontUrl) ?? '' + const path = `${workbenchId}/${control.workspace.workspaceUrl}/${documentId}/${doc._id}` + const link = concatLink(front, path) + return `${document.name}` +} + +/** + * @public + */ +export async function documentTextPresenter (doc: Doc): Promise { + const document = doc as Document + return document.name +} + +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export default async () => ({ + function: { + DocumentHTMLPresenter: documentHTMLPresenter, + DocumentTextPresenter: documentTextPresenter + } +}) diff --git a/server-plugins/document-resources/tsconfig.json b/server-plugins/document-resources/tsconfig.json new file mode 100644 index 0000000000..59e4fd4297 --- /dev/null +++ b/server-plugins/document-resources/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file diff --git a/server-plugins/document/.eslintrc.js b/server-plugins/document/.eslintrc.js new file mode 100644 index 0000000000..72235dc283 --- /dev/null +++ b/server-plugins/document/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/server-plugins/document/.npmignore b/server-plugins/document/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/server-plugins/document/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/server-plugins/document/.prettierignore b/server-plugins/document/.prettierignore new file mode 100644 index 0000000000..21c8f7d149 --- /dev/null +++ b/server-plugins/document/.prettierignore @@ -0,0 +1 @@ +tsdoc-metadata.json \ No newline at end of file diff --git a/server-plugins/document/config/rig.json b/server-plugins/document/config/rig.json new file mode 100644 index 0000000000..0110930f55 --- /dev/null +++ b/server-plugins/document/config/rig.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + "rigPackageName": "@hcengineering/platform-rig" +} diff --git a/server-plugins/document/jest.config.js b/server-plugins/document/jest.config.js new file mode 100644 index 0000000000..2cfd408b67 --- /dev/null +++ b/server-plugins/document/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], + roots: ["./src"], + coverageReporters: ["text-summary", "html"] +} diff --git a/server-plugins/document/package.json b/server-plugins/document/package.json new file mode 100644 index 0000000000..72ff2b6e46 --- /dev/null +++ b/server-plugins/document/package.json @@ -0,0 +1,41 @@ +{ + "name": "@hcengineering/server-document", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "author": "Hardcore Engineering Inc.", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "test": "jest --passWithNoTests --silent", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@types/node": "~20.11.16", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "eslint-config-prettier": "^8.8.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "typescript": "^5.3.3", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "prettier-plugin-svelte": "^3.1.0" + }, + "dependencies": { + "@hcengineering/platform": "^0.6.9", + "@hcengineering/server-core": "^0.6.1", + "@hcengineering/server-notification": "^0.6.1" + } +} diff --git a/server-plugins/document/src/index.ts b/server-plugins/document/src/index.ts new file mode 100644 index 0000000000..9db9cffac0 --- /dev/null +++ b/server-plugins/document/src/index.ts @@ -0,0 +1,23 @@ +// +// Copyright © 2023 Hardcore Engineering Inc. +// +// + +import type { Plugin, Resource } from '@hcengineering/platform' +import { plugin } from '@hcengineering/platform' +import { Presenter } from '@hcengineering/server-notification' + +/** + * @public + */ +export const serverDocumentId = 'server-document' as Plugin + +/** + * @public + */ +export default plugin(serverDocumentId, { + function: { + DocumentHTMLPresenter: '' as Resource, + DocumentTextPresenter: '' as Resource + } +}) diff --git a/server-plugins/document/tsconfig.json b/server-plugins/document/tsconfig.json new file mode 100644 index 0000000000..59e4fd4297 --- /dev/null +++ b/server-plugins/document/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "declarationDir": "./types", + "tsBuildInfoFile": ".build/build.tsbuildinfo" + } +} \ No newline at end of file