From 9d87ce7edef51cb2ceea792cf1095a9f9eec811d Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Thu, 13 Feb 2025 23:41:25 +0500 Subject: [PATCH] Cards fixes (#8003) Signed-off-by: Denis Bykhov --- common/config/rush/pnpm-lock.yaml | 97 +++++++++- dev/prod/package.json | 38 ---- dev/tool/package.json | 2 + dev/tool/src/__start.ts | 2 + models/all/package.json | 1 + models/all/src/index.ts | 7 +- models/card/package.json | 1 + models/card/src/index.ts | 109 +++++++++-- models/card/src/plugin.ts | 4 +- models/server-card/.eslintrc.js | 7 + models/server-card/.npmignore | 4 + models/server-card/config/rig.json | 5 + models/server-card/package.json | 38 ++++ models/server-card/src/index.ts | 39 ++++ models/server-card/tsconfig.json | 10 + packages/presentation/src/search.ts | 34 ++-- packages/presentation/src/types.ts | 1 + packages/query/src/index.ts | 100 +++++++++- packages/query/src/results.ts | 15 +- packages/ui/src/components/Breadcrumbs.svelte | 8 +- .../ui/src/components/NestedDropdown.svelte | 62 +++++++ packages/ui/src/components/NestedMenu.svelte | 119 ++++++++++++ packages/ui/src/index.ts | 2 + plugins/card-assets/assets/icons.svg | 15 +- plugins/card-assets/lang/cs.json | 13 +- plugins/card-assets/lang/de.json | 1 + plugins/card-assets/lang/en.json | 11 +- plugins/card-assets/lang/es.json | 13 +- plugins/card-assets/lang/fr.json | 25 +-- plugins/card-assets/lang/it.json | 11 +- plugins/card-assets/lang/pt.json | 15 +- plugins/card-assets/lang/ru.json | 11 +- plugins/card-assets/lang/zh.json | 15 +- .../src/components/CardPresenter.svelte | 21 +++ .../src/components/EditCard.svelte | 7 +- .../src/components/MasterTagAttributes.svelte | 5 +- .../src/components/MasterTagSelector.svelte | 10 +- .../src/components/Navigator.svelte | 107 +++-------- .../src/components/TagAttributes.svelte | 5 +- .../src/components/TagHierarchy.svelte | 4 +- .../src/components/TagsEditor.svelte | 33 ++-- .../components/settings/ChildsSection.svelte | 84 +++++++++ .../components/settings/GeneralSection.svelte | 84 +++++++++ .../settings/ManageMasterTags.svelte | 165 +++++++++++++++++ .../settings/ManageMasterTagsContent.svelte | 93 ++++++++++ .../settings/ManageMasterTagsTools.svelte | 28 +++ .../settings/MasterTagEditor.svelte | 83 +++++++++ .../settings/ProperitiesSection.svelte | 23 +++ .../settings/RelationsSection.svelte | 82 ++++++++ .../components/settings/TagsHierarchy.svelte | 78 ++++++++ .../components/settings/TagsSection.svelte | 85 +++++++++ plugins/card-resources/src/index.ts | 18 +- plugins/card-resources/src/plugin.ts | 13 +- plugins/card-resources/src/utils.ts | 14 +- plugins/card/package.json | 3 +- plugins/card/src/index.ts | 11 +- plugins/setting-resources/package.json | 1 + .../src/components/AssociationEditor.svelte | 94 ++++++---- .../src/components/ClassAttributeRow.svelte | 5 - .../src/components/ClassAttributes.svelte | 45 +++-- .../components/CreateAttributePopup.svelte | 1 - .../src/components/CreateRelation.svelte | 175 ++++++++++++++++++ .../src/components/EditAttribute.svelte | 7 +- .../src/components/EditRelation.svelte | 112 +++++++++++ .../src/components/RelationSetting.svelte | 70 ++++++- .../src/components/WorkspaceSettings.svelte | 2 +- plugins/setting-resources/src/index.ts | 6 +- plugins/setting/src/index.ts | 4 +- .../src/components/DocTable.svelte | 11 +- .../components/HyperlinkEditorPopup.svelte | 27 --- .../src/components/RelationEditor.svelte | 18 +- .../src/components/filter/FilterBar.svelte | 10 +- .../src/components/filter/FilterButton.svelte | 3 +- plugins/view-resources/src/plugin.ts | 3 +- plugins/view/src/index.ts | 4 +- .../src/components/Navigator.svelte | 7 +- .../src/components/SavedView.svelte | 27 ++- plugins/workbench-resources/src/index.ts | 1 + rush.json | 15 ++ server-plugins/card-resources/.eslintrc.js | 7 + server-plugins/card-resources/.npmignore | 4 + server-plugins/card-resources/config/rig.json | 4 + server-plugins/card-resources/jest.config.js | 7 + server-plugins/card-resources/package.json | 46 +++++ server-plugins/card-resources/src/index.ts | 55 ++++++ server-plugins/card-resources/tsconfig.json | 10 + server-plugins/card/.eslintrc.js | 7 + server-plugins/card/.npmignore | 4 + server-plugins/card/config/rig.json | 4 + server-plugins/card/jest.config.js | 7 + server-plugins/card/package.json | 45 +++++ server-plugins/card/src/index.ts | 32 ++++ server-plugins/card/tsconfig.json | 10 + server/indexer/src/mapper.ts | 9 +- server/server-pipeline/package.json | 2 + server/server-pipeline/src/serverPlugins.ts | 2 + 96 files changed, 2358 insertions(+), 436 deletions(-) create mode 100644 models/server-card/.eslintrc.js create mode 100644 models/server-card/.npmignore create mode 100644 models/server-card/config/rig.json create mode 100644 models/server-card/package.json create mode 100644 models/server-card/src/index.ts create mode 100644 models/server-card/tsconfig.json create mode 100644 packages/ui/src/components/NestedDropdown.svelte create mode 100644 packages/ui/src/components/NestedMenu.svelte create mode 100644 plugins/card-resources/src/components/settings/ChildsSection.svelte create mode 100644 plugins/card-resources/src/components/settings/GeneralSection.svelte create mode 100644 plugins/card-resources/src/components/settings/ManageMasterTags.svelte create mode 100644 plugins/card-resources/src/components/settings/ManageMasterTagsContent.svelte create mode 100644 plugins/card-resources/src/components/settings/ManageMasterTagsTools.svelte create mode 100644 plugins/card-resources/src/components/settings/MasterTagEditor.svelte create mode 100644 plugins/card-resources/src/components/settings/ProperitiesSection.svelte create mode 100644 plugins/card-resources/src/components/settings/RelationsSection.svelte create mode 100644 plugins/card-resources/src/components/settings/TagsHierarchy.svelte create mode 100644 plugins/card-resources/src/components/settings/TagsSection.svelte create mode 100644 plugins/setting-resources/src/components/CreateRelation.svelte create mode 100644 plugins/setting-resources/src/components/EditRelation.svelte create mode 100644 server-plugins/card-resources/.eslintrc.js create mode 100644 server-plugins/card-resources/.npmignore create mode 100644 server-plugins/card-resources/config/rig.json create mode 100644 server-plugins/card-resources/jest.config.js create mode 100644 server-plugins/card-resources/package.json create mode 100644 server-plugins/card-resources/src/index.ts create mode 100644 server-plugins/card-resources/tsconfig.json create mode 100644 server-plugins/card/.eslintrc.js create mode 100644 server-plugins/card/.npmignore create mode 100644 server-plugins/card/config/rig.json create mode 100644 server-plugins/card/jest.config.js create mode 100644 server-plugins/card/package.json create mode 100644 server-plugins/card/src/index.ts create mode 100644 server-plugins/card/tsconfig.json diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 3392b6edb9..5195fe978a 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -475,6 +475,9 @@ importers: '@rush-temp/model-server-calendar': specifier: file:./projects/model-server-calendar.tgz version: file:projects/model-server-calendar.tgz + '@rush-temp/model-server-card': + specifier: file:./projects/model-server-card.tgz + version: file:projects/model-server-card.tgz '@rush-temp/model-server-chunter': specifier: file:./projects/model-server-chunter.tgz version: file:projects/model-server-chunter.tgz @@ -820,6 +823,12 @@ importers: '@rush-temp/server-calendar-resources': specifier: file:./projects/server-calendar-resources.tgz version: file:projects/server-calendar-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + '@rush-temp/server-card': + specifier: file:./projects/server-card.tgz + version: file:projects/server-card.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + '@rush-temp/server-card-resources': + specifier: file:./projects/server-card-resources.tgz + version: file:projects/server-card-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) '@rush-temp/server-chunter': specifier: file:./projects/server-chunter.tgz version: file:projects/server-chunter.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) @@ -3920,7 +3929,7 @@ packages: version: 0.0.0 '@rush-temp/card@file:projects/card.tgz': - resolution: {integrity: sha512-rEy3T9z44ZC/94K3q01+0gbaZ0sJBlwB7KvmQuAbiZMU31t+pzS+yoIYkry7YHm/Ca7kd7H4uvcROiAr7yb91w==, tarball: file:projects/card.tgz} + resolution: {integrity: sha512-/vbzO3L239DHkxNpG5cw/ngDrvuvXrRcoq46Y7uJzNwSNAOMpiiRSMdpj4dr2bmPXEhkFGPeA0mKLJwXLseEhw==, tarball: file:projects/card.tgz} version: 0.0.0 '@rush-temp/chunter-assets@file:projects/chunter-assets.tgz': @@ -4208,7 +4217,7 @@ packages: version: 0.0.0 '@rush-temp/model-all@file:projects/model-all.tgz': - resolution: {integrity: sha512-gkINR6HbfTB1ZSXTI2WHg9B+zIZtcSmb+Bb9fVxbGtq6e+RnxSlOlvjEBoru3ElfIO8x6SYd/KoQhRossQQKnQ==, tarball: file:projects/model-all.tgz} + resolution: {integrity: sha512-aDRtqYlITENsW02SJbs+KjoynFL+/QYQmYQVN6++EqsnAT+jHGPl/UpnmSr3ZMcALGcwTx61LKQ1nnxNen8tyA==, tarball: file:projects/model-all.tgz} version: 0.0.0 '@rush-temp/model-analytics-collector@file:projects/model-analytics-collector.tgz': @@ -4343,6 +4352,10 @@ packages: resolution: {integrity: sha512-tZOPOELF87VVVRzz1CpJN2JWcTMcpO5l+9pbFEB0YHiGZnBd0oujKLMRiSaI4xXiGo0vhA9BjuHpMvcw7zzw0A==, tarball: file:projects/model-server-calendar.tgz} version: 0.0.0 + '@rush-temp/model-server-card@file:projects/model-server-card.tgz': + resolution: {integrity: sha512-SP381dOkAOymE4k9VaEP2o28yv7oJxJEol5LeYjcqHXkyN/al/v8UetEGmS4/gvuxk0Np0KZPpLnczV9O3ApUg==, tarball: file:projects/model-server-card.tgz} + version: 0.0.0 + '@rush-temp/model-server-chunter@file:projects/model-server-chunter.tgz': resolution: {integrity: sha512-qZkbTEVB25W2XQRrvecg/aTQ+kJhY4uBaq6AVGaEf9jS7ZI7NBzk71rXSv9800GGIe0CPWRpSP/453yZQKfNrg==, tarball: file:projects/model-server-chunter.tgz} version: 0.0.0 @@ -4672,7 +4685,7 @@ packages: version: 0.0.0 '@rush-temp/prod@file:projects/prod.tgz': - resolution: {integrity: sha512-m903gPliLrwApgEDgmJCrV74n9agm3V0SYbi3pYOmiVhcY6MPCRk8FprcHnYIW/VAqbzL/Bn8BYnLF8O9IQBLQ==, tarball: file:projects/prod.tgz} + resolution: {integrity: sha512-VeRmwZegE4UJxGZfbKFP55egCMYIBuW6fCawXf1NHcXc93vnE6m9sax3s/O++FU3bMIhusbA0d74ZRRCCozxTw==, tarball: file:projects/prod.tgz} version: 0.0.0 '@rush-temp/products-assets@file:projects/products-assets.tgz': @@ -4803,6 +4816,14 @@ packages: resolution: {integrity: sha512-FQkSKyOpAPE2lnQ6wDRR1ar17olXsmHTWD1vW+ajxSNMuayv4mEVFftAFVfj6b1WvqyuJMiWR8TDv3CRWW5bug==, tarball: file:projects/server-calendar.tgz} version: 0.0.0 + '@rush-temp/server-card-resources@file:projects/server-card-resources.tgz': + resolution: {integrity: sha512-lp3RSXAHV78ux6p3I0iSbVkfY3aB0fXDfxMhxQZfjU9sSXLOsKolgDxMaUNXVm+/WIpS6dwLk4jWHgGopH8Nmw==, tarball: file:projects/server-card-resources.tgz} + version: 0.0.0 + + '@rush-temp/server-card@file:projects/server-card.tgz': + resolution: {integrity: sha512-ATIgXsB+SGQDQHyZqzQ8ooD/yAjqyimZzjMVZLMFJvRQenPLZEwdW0D+ikWila7ixB115IvKtGhrM8y7mvnMog==, tarball: file:projects/server-card.tgz} + version: 0.0.0 + '@rush-temp/server-chunter-resources@file:projects/server-chunter-resources.tgz': resolution: {integrity: sha512-anzs0C7AXicSpf9F+jjqdokc3cZunw5O8gC0095fQmEoOW94OmvTyboGrx8iK3i+iYam4Z6Bkt60rXRo3JvXZQ==, tarball: file:projects/server-chunter-resources.tgz} version: 0.0.0 @@ -4940,7 +4961,7 @@ packages: version: 0.0.0 '@rush-temp/server-pipeline@file:projects/server-pipeline.tgz': - resolution: {integrity: sha512-AEDx9sHjL/Dh1KCJ0DiICkS4JZ24HrqPlz4Wp09xmI9d3q35DpCS2oP8+qUjSF1qX5kZSIu0GrDshztCFYQScQ==, tarball: file:projects/server-pipeline.tgz} + resolution: {integrity: sha512-fmLSX42maXiVGBW3TM2hB1y5UG+weaJSBpInOVUMf/5Y59N3s0rACYuHR+wuzcmIdIRiXKMN7ypET7mz4sxT2g==, tarball: file:projects/server-pipeline.tgz} version: 0.0.0 '@rush-temp/server-preference@file:projects/server-preference.tgz': @@ -5056,7 +5077,7 @@ packages: version: 0.0.0 '@rush-temp/setting-resources@file:projects/setting-resources.tgz': - resolution: {integrity: sha512-XudJm31jzp8dEwS9TsP8lpxB2/yYjvafLULunIlgG46LdhQBfDG711m9w9gLb41Jj9O1quj2egHI87fHfmwrrg==, tarball: file:projects/setting-resources.tgz} + resolution: {integrity: sha512-FVaGM7H5JXFKHZ7thrdx9tj94krIQWzJ61p/QXBwhW78ycK9lNliYCHP0pLMA+rsScxAdmR6wa7n7nRO5XBGbw==, tarball: file:projects/setting-resources.tgz} version: 0.0.0 '@rush-temp/setting@file:projects/setting.tgz': @@ -5204,7 +5225,7 @@ packages: version: 0.0.0 '@rush-temp/tool@file:projects/tool.tgz': - resolution: {integrity: sha512-dMjmwZoox3cdyn4o7EY2NL8Kst4si0xI+HT9YSnaQd7A4cBwapn/oXi163xq2f9mOhf2oekXpt2iT1hK8JoQQQ==, tarball: file:projects/tool.tgz} + resolution: {integrity: sha512-1/Aodec9LySBThOZAeA3XJfP83lSVTVRFdlb8uNTORq1sHJxCADx9BliCh2dTzdhydW46wcAxMPeArhopkcN1Q==, tarball: file:projects/tool.tgz} version: 0.0.0 '@rush-temp/tracker-assets@file:projects/tracker-assets.tgz': @@ -19404,6 +19425,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@rush-temp/model-server-card@file:projects/model-server-card.tgz': + dependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + prettier: 3.2.5 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + '@rush-temp/model-server-chunter@file:projects/model-server-chunter.tgz': dependencies: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3) @@ -22459,6 +22494,56 @@ snapshots: - supports-color - ts-node + '@rush-temp/server-card-resources@file:projects/server-card-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': + dependencies: + '@types/jest': 29.5.12 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + prettier: 3.2.5 + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + + '@rush-temp/server-card@file:projects/server-card.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': + dependencies: + '@types/jest': 29.5.12 + '@types/node': 20.11.19 + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.7.3) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.7.3) + eslint: 8.56.0 + eslint-config-standard-with-typescript: 40.0.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint-plugin-n@15.7.0(eslint@8.56.0))(eslint-plugin-promise@6.1.1(eslint@8.56.0))(eslint@8.56.0)(typescript@5.7.3) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)) + prettier: 3.2.5 + ts-jest: 29.1.2(@babel/core@7.23.9)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3)))(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + '@rush-temp/server-chunter-resources@file:projects/server-chunter-resources.tgz(@babel/core@7.23.9)(@jest/types@29.6.3)(@types/node@20.11.19)(babel-jest@29.7.0(@babel/core@7.23.9))(esbuild@0.24.2)(ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3))': dependencies: '@types/jest': 29.5.12 diff --git a/dev/prod/package.json b/dev/prod/package.json index 36f1d360c1..aa685c2f8a 100644 --- a/dev/prod/package.json +++ b/dev/prod/package.json @@ -110,16 +110,6 @@ "@hcengineering/inventory": "^0.6.11", "@hcengineering/inventory-assets": "^0.6.11", "@hcengineering/inventory-resources": "^0.6.0", - "@hcengineering/server-attachment": "^0.6.1", - "@hcengineering/server-attachment-resources": "^0.6.0", - "@hcengineering/server-collaboration": "^0.6.0", - "@hcengineering/server-collaboration-resources": "^0.6.0", - "@hcengineering/server-contact": "^0.6.1", - "@hcengineering/server-contact-resources": "^0.6.0", - "@hcengineering/server-notification": "^0.6.1", - "@hcengineering/server-notification-resources": "^0.6.0", - "@hcengineering/server-setting": "^0.6.0", - "@hcengineering/server-setting-resources": "^0.6.0", "@hcengineering/templates": "^0.6.11", "@hcengineering/templates-assets": "^0.6.11", "@hcengineering/templates-resources": "^0.6.0", @@ -133,30 +123,10 @@ "@hcengineering/tags-assets": "^0.6.0", "@hcengineering/tags": "^0.6.16", "@hcengineering/tags-resources": "^0.6.0", - "@hcengineering/server-chunter": "^0.6.0", - "@hcengineering/server-chunter-resources": "^0.6.0", - "@hcengineering/server-inventory": "^0.6.1", - "@hcengineering/server-inventory-resources": "^0.6.0", - "@hcengineering/server-lead": "^0.6.0", - "@hcengineering/server-lead-resources": "^0.6.0", - "@hcengineering/server-recruit": "^0.6.0", - "@hcengineering/server-recruit-resources": "^0.6.0", - "@hcengineering/server-tags": "^0.6.0", - "@hcengineering/server-tags-resources": "^0.6.0", - "@hcengineering/server-task": "^0.6.0", - "@hcengineering/server-task-resources": "^0.6.0", "@hcengineering/calendar": "^0.6.24", "@hcengineering/calendar-assets": "^0.6.22", "@hcengineering/calendar-resources": "^0.6.0", - "@hcengineering/server-calendar": "^0.6.0", - "@hcengineering/server-calendar-resources": "^0.6.0", - "@hcengineering/server-gmail": "^0.6.0", - "@hcengineering/server-gmail-resources": "^0.6.0", - "@hcengineering/server-telegram": "^0.6.0", - "@hcengineering/server-telegram-resources": "^0.6.0", "@hcengineering/presentation": "^0.6.3", - "@hcengineering/server-tracker": "^0.6.0", - "@hcengineering/server-tracker-resources": "^0.6.0", "@hcengineering/tracker": "^0.6.24", "@hcengineering/tracker-assets": "^0.6.0", "@hcengineering/tracker-resources": "^0.6.0", @@ -169,20 +139,12 @@ "@hcengineering/hr": "^0.6.19", "@hcengineering/hr-assets": "^0.6.19", "@hcengineering/hr-resources": "^0.6.0", - "@hcengineering/server-hr": "^0.6.0", - "@hcengineering/server-hr-resources": "^0.6.0", "@hcengineering/bitrix": "^0.6.52", "@hcengineering/bitrix-assets": "^0.6.0", "@hcengineering/bitrix-resources": "^0.6.0", "@hcengineering/request": "^0.6.14", "@hcengineering/request-assets": "^0.6.0", "@hcengineering/request-resources": "^0.6.0", - "@hcengineering/server-request": "^0.6.0", - "@hcengineering/server-request-resources": "^0.6.0", - "@hcengineering/server-view": "^0.6.0", - "@hcengineering/server-view-resources": "^0.6.0", - "@hcengineering/server-activity": "^0.6.0", - "@hcengineering/server-activity-resources": "^0.6.0", "@hcengineering/drive": "^0.6.0", "@hcengineering/drive-assets": "^0.6.0", "@hcengineering/drive-resources": "^0.6.0", diff --git a/dev/tool/package.json b/dev/tool/package.json index 4ab6044cbb..52e28f37b7 100644 --- a/dev/tool/package.json +++ b/dev/tool/package.json @@ -101,6 +101,8 @@ "@hcengineering/server-storage": "^0.6.0", "@hcengineering/server-calendar": "^0.6.0", "@hcengineering/server-calendar-resources": "^0.6.0", + "@hcengineering/server-card": "^0.6.0", + "@hcengineering/server-card-resources": "^0.6.0", "@hcengineering/server-chunter": "^0.6.0", "@hcengineering/server-chunter-resources": "^0.6.0", "@hcengineering/server-contact": "^0.6.1", diff --git a/dev/tool/src/__start.ts b/dev/tool/src/__start.ts index a0c33c3d39..031a099d3c 100644 --- a/dev/tool/src/__start.ts +++ b/dev/tool/src/__start.ts @@ -23,6 +23,7 @@ import { devTool } from '.' import { addLocation } from '@hcengineering/platform' import { serverActivityId } from '@hcengineering/server-activity' import { serverAttachmentId } from '@hcengineering/server-attachment' +import { serverCardId } from '@hcengineering/server-card' import { serverCalendarId } from '@hcengineering/server-calendar' import { serverChunterId } from '@hcengineering/server-chunter' import { serverCollaborationId } from '@hcengineering/server-collaboration' @@ -59,6 +60,7 @@ addLocation(serverSettingId, () => import('@hcengineering/server-setting-resourc addLocation(serverTaskId, () => import('@hcengineering/server-task-resources')) addLocation(serverTrackerId, () => import('@hcengineering/server-tracker-resources')) addLocation(serverTagsId, () => import('@hcengineering/server-tags-resources')) +addLocation(serverCardId, () => import('@hcengineering/server-card-resources')) addLocation(serverCalendarId, () => import('@hcengineering/server-calendar-resources')) addLocation(serverGmailId, () => import('@hcengineering/server-gmail-resources')) addLocation(serverTelegramId, () => import('@hcengineering/server-telegram-resources')) diff --git a/models/all/package.json b/models/all/package.json index 1333fcf4ab..9069c256d1 100644 --- a/models/all/package.json +++ b/models/all/package.json @@ -87,6 +87,7 @@ "@hcengineering/model-bitrix": "^0.6.0", "@hcengineering/model-request": "^0.6.0", "@hcengineering/model-support": "^0.6.0", + "@hcengineering/model-server-card": "^0.6.0", "@hcengineering/model-server-request": "^0.6.0", "@hcengineering/model-server-view": "^0.6.0", "@hcengineering/model-server-activity": "^0.6.0", diff --git a/models/all/src/index.ts b/models/all/src/index.ts index 84af4267c5..e80c6707d2 100644 --- a/models/all/src/index.ts +++ b/models/all/src/index.ts @@ -37,6 +37,7 @@ import { requestId, createModel as requestModel } from '@hcengineering/model-req import { aiBotId, createModel as aiBotModel } from '@hcengineering/model-ai-bot' import { serverActivityId, createModel as serverActivityModel } from '@hcengineering/model-server-activity' import { serverAttachmentId, createModel as serverAttachmentModel } from '@hcengineering/model-server-attachment' +import { serverCardId, createModel as serverCardModel } from '@hcengineering/model-server-card' import { serverCalendarId, createModel as serverCalendarModel } from '@hcengineering/model-server-calendar' import { serverChunterId, createModel as serverChunterModel } from '@hcengineering/model-server-chunter' import { @@ -146,7 +147,8 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[ view.class.Action, contact.class.ChannelProvider, setting.class.IntegrationType, - setting.class.WorkspaceSettingCategory + setting.class.WorkspaceSettingCategory, + setting.class.SettingsCategory ] const builders: BuilderConfig[] = [ @@ -366,7 +368,7 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[ { label: card.string.Cards, description: card.string.ConfigDescription, - enabled: false, + enabled: true, beta: true, icon: card.icon.Card, classFilter: defaultFilter @@ -440,6 +442,7 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[ [serverTagsModel, serverTagsId], [serverTaskModel, serverTaskId], [serverTrackerModel, serverTrackerId], + [serverCardModel, serverCardId], [serverCalendarModel, serverCalendarId], [serverRecruitModel, serverRecruitId], [serverGmailModel, serverGmailId], diff --git a/models/card/package.json b/models/card/package.json index bf728b4196..2e5e34f2cf 100644 --- a/models/card/package.json +++ b/models/card/package.json @@ -29,6 +29,7 @@ }, "dependencies": { "@hcengineering/activity": "^0.6.0", + "@hcengineering/contact": "^0.6.24", "@hcengineering/core": "^0.6.32", "@hcengineering/model": "^0.6.11", "@hcengineering/chunter": "^0.6.20", diff --git a/models/card/src/index.ts b/models/card/src/index.ts index 77359bc242..e36e4f342d 100644 --- a/models/card/src/index.ts +++ b/models/card/src/index.ts @@ -14,8 +14,11 @@ import activity from '@hcengineering/activity' import { CardEvents, cardId, type Card, type MasterTag, type Tag } from '@hcengineering/card' import chunter from '@hcengineering/chunter' +import contact from '@hcengineering/contact' import core, { AccountRole, + DOMAIN_MODEL, + IndexKind, type CollectionSize, type Domain, type MarkupBlobRef, @@ -24,12 +27,12 @@ import core, { } from '@hcengineering/core' import { Collection, + Index, Model, Prop, TypeCollaborativeDoc, TypeRef, TypeString, - UX, type Builder } from '@hcengineering/model' import attachment from '@hcengineering/model-attachment' @@ -38,8 +41,9 @@ import presentation from '@hcengineering/model-presentation' import setting from '@hcengineering/model-setting' import view, { createAction } from '@hcengineering/model-view' import workbench from '@hcengineering/model-workbench' -import { getEmbeddedLabel } from '@hcengineering/platform' +import { getEmbeddedLabel, type IntlString } from '@hcengineering/platform' import time, { type ToDo } from '@hcengineering/time' +import { type AnyComponent } from '@hcengineering/ui' import card from './plugin' export { cardId } from '@hcengineering/card' @@ -53,12 +57,12 @@ export class TMasterTag extends TClass implements MasterTag {} export class TTag extends TMixin implements Tag {} @Model(card.class.Card, core.class.Doc, DOMAIN_CARD) -@UX(card.string.Card) export class TCard extends TDoc implements Card { @Prop(TypeRef(card.class.MasterTag), card.string.MasterTag) declare _class: Ref @Prop(TypeString(), core.string.Name) + @Index(IndexKind.FullText) title!: string @Prop(TypeCollaborativeDoc(), card.string.Content) @@ -75,8 +79,15 @@ export class TCard extends TDoc implements Card { todos?: CollectionSize } +@Model(card.class.MasterTagEditorSection, core.class.Doc, DOMAIN_MODEL) +export class MasterTagEditorSection extends TDoc implements MasterTagEditorSection { + id!: string + label!: IntlString + component!: AnyComponent +} + export function createModel (builder: Builder): void { - builder.createModel(TMasterTag, TTag, TCard) + builder.createModel(TMasterTag, TTag, TCard, MasterTagEditorSection) builder.createDoc( workbench.class.Application, @@ -113,20 +124,6 @@ export function createModel (builder: Builder): void { card.viewlet.CardTable ) - builder.createDoc( - setting.class.WorkspaceSettingCategory, - core.space.Model, - { - name: 'masterTags', - label: card.string.Tags, - icon: card.icon.Tags, - role: AccountRole.User, - component: card.component.MasterTags, - order: 4400 - }, - card.ids.MasterTags - ) - builder.mixin(card.class.Card, core.class.Class, view.mixin.ObjectPresenter, { presenter: card.component.CardPresenter }) @@ -268,11 +265,55 @@ export function createModel (builder: Builder): void { } }) + builder.createDoc( + setting.class.WorkspaceSettingCategory, + core.space.Model, + { + name: 'tagrelation', + label: card.string.TagRelations, + icon: setting.icon.Relations, + props: { _classes: [card.class.Card, contact.class.Contact], exclude: [] }, + component: setting.component.RelationSetting, + group: 'settings-editor', + role: AccountRole.Maintainer, + order: 4501 + }, + card.ids.TagRelations + ) + + builder.createDoc( + setting.class.SettingsCategory, + core.space.Model, + { + name: 'masterTags', + label: card.string.MasterTags, + icon: card.icon.Card, + component: card.component.ManageMasterTagsContent, + extraComponents: { + navigation: card.component.ManageMasterTags, + tools: card.component.ManageMasterTagsTools + }, + group: 'settings-editor', + role: AccountRole.User, + order: 5000, + expandable: true + }, + card.ids.ManageMasterTags + ) + builder.mixin(card.class.Card, core.class.Class, view.mixin.ClassFilters, { filters: [], ignoreKeys: ['parent'] }) + builder.createDoc(core.class.FullTextSearchContext, core.space.Model, { + toClass: card.class.Card, + fullTextSummary: true, + forceIndex: true, + childProcessingAllowed: true, + propagate: [] + }) + builder.createDoc( presentation.class.ObjectSearchCategory, core.space.Model, @@ -283,10 +324,42 @@ export function createModel (builder: Builder): void { query: card.completion.CardQuery, context: ['search', 'mention', 'spotlight'], classToSearch: card.class.Card, + includeChilds: true, priority: 500 }, card.completion.CardCategory ) + + builder.createDoc(card.class.MasterTagEditorSection, core.space.Model, { + id: 'general', + label: setting.string.General, + component: card.component.GeneralSection + }) + + builder.createDoc(card.class.MasterTagEditorSection, core.space.Model, { + id: 'properties', + label: setting.string.Properties, + component: card.component.ProperitiesSection + }) + + builder.createDoc(card.class.MasterTagEditorSection, core.space.Model, { + id: 'tags', + label: card.string.Tags, + component: card.component.TagsSection + }) + + builder.createDoc(card.class.MasterTagEditorSection, core.space.Model, { + id: 'childs', + label: card.string.MasterTags, + masterOnly: true, + component: card.component.ChildsSection + }) + + builder.createDoc(card.class.MasterTagEditorSection, core.space.Model, { + id: 'relations', + label: core.string.Relations, + component: card.component.RelationsSection + }) } export default card diff --git a/models/card/src/plugin.ts b/models/card/src/plugin.ts index c13200793e..ef1ce2aa73 100644 --- a/models/card/src/plugin.ts +++ b/models/card/src/plugin.ts @@ -34,7 +34,9 @@ export default mergeIds(cardId, card, { DeleteMasterTag: '' as Ref }, ids: { - MasterTags: '' as Ref + MasterTags: '' as Ref, + ManageMasterTags: '' as Ref, + TagRelations: '' as Ref }, completion: { CardQuery: '' as Resource, diff --git a/models/server-card/.eslintrc.js b/models/server-card/.eslintrc.js new file mode 100644 index 0000000000..c1cf82cba0 --- /dev/null +++ b/models/server-card/.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-card/.npmignore b/models/server-card/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/models/server-card/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/models/server-card/config/rig.json b/models/server-card/config/rig.json new file mode 100644 index 0000000000..2f6be36605 --- /dev/null +++ b/models/server-card/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-card/package.json b/models/server-card/package.json new file mode 100644 index 0000000000..4963a01656 --- /dev/null +++ b/models/server-card/package.json @@ -0,0 +1,38 @@ +{ + "name": "@hcengineering/model-server-card", + "version": "0.6.0", + "main": "lib/index.js", + "svelte": "src/index.ts", + "types": "types/index.d.ts", + "author": "Anticrm Platform Contributors", + "template": "@hcengineering/model-package", + "license": "EPL-2.0", + "scripts": { + "build": "compile", + "build:watch": "compile", + "format": "format src", + "_phase:build": "compile transpile src", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.54.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "prettier": "^3.1.0", + "typescript": "^5.3.3" + }, + "dependencies": { + "@hcengineering/core": "^0.6.32", + "@hcengineering/model": "^0.6.11", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/card": "^0.6.0", + "@hcengineering/server-card": "^0.6.0", + "@hcengineering/server-core": "^0.6.1" + } +} diff --git a/models/server-card/src/index.ts b/models/server-card/src/index.ts new file mode 100644 index 0000000000..f26ef63727 --- /dev/null +++ b/models/server-card/src/index.ts @@ -0,0 +1,39 @@ +// +// Copyright © 2025 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { type Builder } from '@hcengineering/model' + +import core from '@hcengineering/core' +import serverCore from '@hcengineering/server-core' +import serverCard from '@hcengineering/server-card' +import card from '@hcengineering/card' + +export { serverCardId } from '@hcengineering/server-card' + +export function createModel (builder: Builder): void { + builder.createDoc(serverCore.class.Trigger, core.space.Model, { + trigger: serverCard.trigger.OnAttribute, + isAsync: true, + txMatch: { + _class: core.class.TxCreateDoc, + objectClass: core.class.Attribute + } + }) + + builder.mixin(card.class.Card, core.class.Class, serverCore.mixin.SearchPresenter, { + searchIcon: card.icon.Card, + title: [['title']] + }) +} diff --git a/models/server-card/tsconfig.json b/models/server-card/tsconfig.json new file mode 100644 index 0000000000..9765b6086d --- /dev/null +++ b/models/server-card/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/packages/presentation/src/search.ts b/packages/presentation/src/search.ts index 01ab3f83ce..965f9d244f 100644 --- a/packages/presentation/src/search.ts +++ b/packages/presentation/src/search.ts @@ -32,18 +32,6 @@ export interface SearchItem { category: ObjectSearchCategory } -function findCategoryByClass ( - categories: ObjectSearchCategory[], - _class: Ref> -): ObjectSearchCategory | undefined { - for (const category of categories) { - if (category.classToSearch === _class) { - return category - } - } - return undefined -} - function packSearchResultsForListView (sections: SearchSection[]): SearchItem[] { let results: SearchItem[] = [] for (const section of sections) { @@ -63,35 +51,37 @@ function packSearchResultsForListView (sections: SearchSection[]): SearchItem[] async function searchCategory ( client: TxOperations, - cl: Ref>, + category: ObjectSearchCategory, query: string, - categories: ObjectSearchCategory[], limit?: number ): Promise { + if (category.classToSearch === undefined) return + const classes = + category.includeChilds === true + ? client.getHierarchy().getDescendants(category.classToSearch) + : [category.classToSearch] const r = await client.searchFulltext( { query: `${query}*`, - classes: [cl] + classes }, { limit: limit ?? 5 } ) - const category = findCategoryByClass(categories, cl) - return category !== undefined ? { category, items: r.docs } : undefined + return { category, items: r.docs } } async function doFulltextSearch ( client: TxOperations, - classes: Array>>, - query: string, categories: ObjectSearchCategory[], + query: string, limit?: number ): Promise { const sections: SearchSection[] = [] const promises: Array> = [] - for (const cl of classes) { - promises.push(searchCategory(client, cl, query, categories, limit)) + for (const cat of categories) { + promises.push(searchCategory(client, cat, query, limit)) } const resolvedSections = await Promise.all(promises) @@ -140,6 +130,6 @@ export async function searchFor ( } } - const sections = await doFulltextSearch(client, classesToSearch, query, categories, limit) + const sections = await doFulltextSearch(client, cats, query, limit) return { items: packSearchResultsForListView(sections), query } } diff --git a/packages/presentation/src/types.ts b/packages/presentation/src/types.ts index 9e9a09b5f2..0dbcd69ac3 100644 --- a/packages/presentation/src/types.ts +++ b/packages/presentation/src/types.ts @@ -72,6 +72,7 @@ export interface ObjectSearchCategory extends Doc { // Query for documents with pattern query: Resource classToSearch?: Ref> + includeChilds?: boolean priority?: number } diff --git a/packages/query/src/index.ts b/packages/query/src/index.ts index d219db9530..4f8cd2c5c0 100644 --- a/packages/query/src/index.ts +++ b/packages/query/src/index.ts @@ -15,6 +15,7 @@ import { Analytics } from '@hcengineering/analytics' import core, { + Association, BulkUpdateEvent, Class, Client, @@ -30,6 +31,7 @@ import core, { Mixin, ModelDb, Ref, + Relation, ReverseLookups, SearchOptions, SearchQuery, @@ -659,6 +661,7 @@ export class LiveQuery implements WithTx, Client { } } await this.handleDocUpdateLookup(q, tx) + await this.handleDocUpdateRelation(q, tx) } } return {} @@ -724,6 +727,50 @@ export class LiveQuery implements WithTx, Client { return } await this.handleDocUpdateLookup(q, tx) + await this.handleDocUpdateRelation(q, tx) + } + + private isPossibleAssociationTx (tx: TxUpdateDoc | TxMixin, association: Association): boolean { + const h = this.getHierarchy() + const byClass = + h.isDerived(tx.objectClass, association.classA) || + h.isDerived(tx.objectClass, association.classB) || + h.isDerived(association.classA, tx.objectClass) || + h.isDerived(association.classB, tx.objectClass) + if (byClass) { + return true + } + if (tx._class === core.class.TxMixin) { + const mixinTx = tx as TxMixin + return h.isDerived(mixinTx.mixin, association.classA) || h.isDerived(mixinTx.mixin, association.classB) + } + return false + } + + private async handleDocUpdateRelation (q: Query, tx: TxUpdateDoc | TxMixin): Promise { + if (q.options?.associations === undefined) return + for (const assoc of q.options.associations) { + const association = this.getModel().findObject(assoc[0]) + if (association === undefined) continue + if (this.isPossibleAssociationTx(tx, association)) { + if (q.result instanceof Promise) { + q.result = await q.result + } + const docs = q.result.getDocs() + for (const doc of docs) { + const docToUpdate = doc.$associations?.[association._id].find((it) => it._id === tx.objectId) + if (docToUpdate !== undefined) { + if (tx._class === core.class.TxMixin) { + TxProcessor.updateMixin4Doc(docToUpdate, tx as TxMixin) + } else { + TxProcessor.updateDoc2Doc(docToUpdate, tx as TxUpdateDoc) + } + q.result.updateDoc(doc, false) + this.queriesToUpdate.set(q.id, q) + } + } + } + } } private async handleDocUpdateLookup (q: Query, tx: TxUpdateDoc | TxMixin): Promise { @@ -971,6 +1018,7 @@ export class LiveQuery implements WithTx, Client { } await this.handleDocAddLookup(q, doc) + await this.handleDocAddRelation(q, doc) } } return {} @@ -1039,6 +1087,35 @@ export class LiveQuery implements WithTx, Client { } } + private async handleDocAddRelation (q: Query, doc: Doc): Promise { + if (q.options?.associations === undefined) return + if (doc._class !== core.class.Relation) return + const relation = doc as Relation + const assoc = q.options.associations.find((p) => p[0] === relation.association) + if (assoc !== undefined) { + if (q.result instanceof Promise) { + q.result = await q.result + } + const direct = assoc[1] === 1 + const res = q.result.findDoc(direct ? relation.docA : relation.docB) + if (res === undefined) return + const association = this.getModel().findObject(assoc[0]) + if (association === undefined) return + const docToPush = await this.findOne(!direct ? association.classB : association.classA, { + _id: direct ? relation.docB : relation.docA + }) + if (docToPush === undefined) return + const arr = res?.$associations?.[relation.association] ?? [] + arr.push(docToPush) + if (res?.$associations === undefined) { + res.$associations = {} + } + res.$associations[relation.association] = arr + q.result.updateDoc(res, false) + this.queriesToUpdate.set(q.id, q) + } + } + private async handleDocAddLookup (q: Query, doc: Doc): Promise { if (q.options?.lookup === undefined) return const lookup = q.options.lookup @@ -1120,16 +1197,16 @@ export class LiveQuery implements WithTx, Client { if (q.result instanceof Promise) { q.result = await q.result } - if ( - q.options?.limit !== undefined && - q.options.limit === q.result.length && - h.isDerived(q._class, tx.objectClass) - ) { - await this.refresh(q) - return - } const index = q.result.getDocs().find((p) => p._id === tx.objectId && h.isDerived(p._class, tx.objectClass)) if (index !== undefined) { + if ( + q.options?.limit !== undefined && + q.options.limit === q.result.length && + h.isDerived(q._class, tx.objectClass) + ) { + await this.refresh(q) + return + } q.result.delete(index._id) this.refs.updateDocuments(q, [index], true) @@ -1139,6 +1216,13 @@ export class LiveQuery implements WithTx, Client { await this.callback(q, true) } await this.handleDocRemoveLookup(q, tx) + await this.handleDocRemoveRelation(q, tx) + } + + private async handleDocRemoveRelation (q: Query, tx: TxRemoveDoc): Promise { + if (q.options?.associations === undefined) return + if (tx.objectClass !== core.class.Relation) return + await this.refresh(q) } private async handleDocRemoveLookup (q: Query, tx: TxRemoveDoc): Promise { diff --git a/packages/query/src/results.ts b/packages/query/src/results.ts index f9b2dbfe44..bc10576de8 100644 --- a/packages/query/src/results.ts +++ b/packages/query/src/results.ts @@ -1,5 +1,6 @@ import { resultSort, + WithLookup, type Class, type Doc, type Hierarchy, @@ -9,9 +10,9 @@ import { } from '@hcengineering/core' export class ResultArray { - private docs: Map, Doc> + private docs: Map, WithLookup> - private readonly clones = new Map, Doc>>() + private readonly clones = new Map, WithLookup>>() get length (): number { return this.docs.size @@ -28,11 +29,11 @@ export class ResultArray { this.clones.clear() } - getDocs (): Doc[] { + getDocs (): WithLookup[] { return Array.from(this.docs.values()) } - findDoc (_id: Ref): Doc | undefined { + findDoc (_id: Ref): WithLookup | undefined { return this.docs.get(_id) } @@ -61,14 +62,14 @@ export class ResultArray { return doc } - updateDoc (doc: Doc, mainClone = true): void { + updateDoc (doc: WithLookup, mainClone = true): void { this.docs.set(doc._id, mainClone ? this.hierarchy.clone(doc) : doc) for (const [, v] of this.clones.entries()) { v.set(doc._id, this.hierarchy.clone(doc)) } } - push (doc: Doc): void { + push (doc: WithLookup): void { this.docs.set(doc._id, this.hierarchy.clone(doc)) for (const [, v] of this.clones.entries()) { v.set(doc._id, this.hierarchy.clone(doc)) @@ -76,7 +77,7 @@ export class ResultArray { // this.changes.add(doc._id) } - pop (): Doc | undefined { + pop (): WithLookup | undefined { const lastElement = Array.from(this.docs)[this.docs.size - 1] if (lastElement !== undefined) { this.docs.delete(lastElement[0]) diff --git a/packages/ui/src/components/Breadcrumbs.svelte b/packages/ui/src/components/Breadcrumbs.svelte index 4f7cc3c84b..c49d0ca9a3 100644 --- a/packages/ui/src/components/Breadcrumbs.svelte +++ b/packages/ui/src/components/Breadcrumbs.svelte @@ -13,12 +13,12 @@ // limitations under the License. --> + +
+ +
diff --git a/packages/ui/src/components/NestedMenu.svelte b/packages/ui/src/components/NestedMenu.svelte new file mode 100644 index 0000000000..c2e0464e23 --- /dev/null +++ b/packages/ui/src/components/NestedMenu.svelte @@ -0,0 +1,119 @@ + + + +
dispatch('changeContent')}> +