diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index ac764607ff..c5b4f2ea68 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -110,6 +110,7 @@ specifiers: '@rush-temp/model-server-telegram': file:./projects/model-server-telegram.tgz '@rush-temp/model-server-tracker': file:./projects/model-server-tracker.tgz '@rush-temp/model-server-translate': file:./projects/model-server-translate.tgz + '@rush-temp/model-server-view': file:./projects/model-server-view.tgz '@rush-temp/model-setting': file:./projects/model-setting.tgz '@rush-temp/model-tags': file:./projects/model-tags.tgz '@rush-temp/model-task': file:./projects/model-task.tgz @@ -182,6 +183,8 @@ specifiers: '@rush-temp/server-tool': file:./projects/server-tool.tgz '@rush-temp/server-tracker': file:./projects/server-tracker.tgz '@rush-temp/server-tracker-resources': file:./projects/server-tracker-resources.tgz + '@rush-temp/server-view': file:./projects/server-view.tgz + '@rush-temp/server-view-resources': file:./projects/server-view-resources.tgz '@rush-temp/server-ws': file:./projects/server-ws.tgz '@rush-temp/setting': file:./projects/setting.tgz '@rush-temp/setting-assets': file:./projects/setting-assets.tgz @@ -474,6 +477,7 @@ dependencies: '@rush-temp/model-server-telegram': file:projects/model-server-telegram.tgz_typescript@4.8.4 '@rush-temp/model-server-tracker': file:projects/model-server-tracker.tgz_typescript@4.8.4 '@rush-temp/model-server-translate': file:projects/model-server-translate.tgz_typescript@4.8.4 + '@rush-temp/model-server-view': file:projects/model-server-view.tgz_typescript@4.8.4 '@rush-temp/model-setting': file:projects/model-setting.tgz_typescript@4.8.4 '@rush-temp/model-tags': file:projects/model-tags.tgz_typescript@4.8.4 '@rush-temp/model-task': file:projects/model-task.tgz_typescript@4.8.4 @@ -546,6 +550,8 @@ dependencies: '@rush-temp/server-tool': file:projects/server-tool.tgz '@rush-temp/server-tracker': file:projects/server-tracker.tgz '@rush-temp/server-tracker-resources': file:projects/server-tracker-resources.tgz + '@rush-temp/server-view': file:projects/server-view.tgz + '@rush-temp/server-view-resources': file:projects/server-view-resources.tgz '@rush-temp/server-ws': file:projects/server-ws.tgz '@rush-temp/setting': file:projects/setting.tgz '@rush-temp/setting-assets': file:projects/setting-assets.tgz_typescript@4.8.4 @@ -13928,6 +13934,27 @@ packages: - typescript dev: false + file:projects/model-server-view.tgz_typescript@4.8.4: + resolution: {integrity: sha512-HR5bDOxNyYzuSEipU7LF5taOi/WHj9APHAxBN/3S5d5mNyc3vEYqfP4KPcb88iAd6oqhGVlz0+OyeTNa9vDaVQ==, tarball: file:projects/model-server-view.tgz} + id: file:projects/model-server-view.tgz + name: '@rush-temp/model-server-view' + version: 0.0.0 + dependencies: + '@rushstack/heft': 0.47.11 + '@types/heft-jest': 1.0.3 + '@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464 + '@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4 + eslint: 8.27.0 + eslint-config-standard-with-typescript: 23.0.0_c9fe9619f50f4e82337a86c3af25e566 + eslint-plugin-import: 2.26.0_eslint@8.27.0 + eslint-plugin-n: 15.5.1_eslint@8.27.0 + eslint-plugin-promise: 6.1.1_eslint@8.27.0 + prettier: 2.7.1 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + file:projects/model-setting.tgz_typescript@4.8.4: resolution: {integrity: sha512-VNYzzzsdvUfp71pgoPt52l+/VZ8/OV5JQJIDLOuT/2KkQEepZRaR+DZ2HXCg5v8Jvu/t/a9tQTPDN4juziuVew==, tarball: file:projects/model-setting.tgz} id: file:projects/model-setting.tgz @@ -14076,7 +14103,7 @@ packages: dev: false file:projects/model-view.tgz_typescript@4.8.4: - resolution: {integrity: sha512-xSdAkhRAW0NreiqzR/EeLXsGTLhzGMIjTyZ7wi07R/ee3gl7kAib1GMQIEcTqVAyFiDlDkmL9h+yTap51ltCvA==, tarball: file:projects/model-view.tgz} + resolution: {integrity: sha512-8TFptqZhGtZrzBg2N8VegpTjkQdWZGPB0FaWwgl9aChJPy6LJsyI8Z+7YV26P9n2tq00U+6tNlJ8mbbd9Exd7g==, tarball: file:projects/model-view.tgz} id: file:projects/model-view.tgz name: '@rush-temp/model-view' version: 0.0.0 @@ -15645,6 +15672,47 @@ packages: - supports-color dev: false + file:projects/server-view-resources.tgz: + resolution: {integrity: sha512-h274HGDdQNcR3rqg/86yqdVMQLD+wKxK24hbej8L+kpbm5l03V9c7mvm9h1LJJrZrG7Zztf2V6+J82iTq65uRg==, tarball: file:projects/server-view-resources.tgz} + name: '@rush-temp/server-view-resources' + version: 0.0.0 + dependencies: + '@rushstack/heft': 0.47.11 + '@types/heft-jest': 1.0.3 + '@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464 + '@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4 + eslint: 8.27.0 + eslint-config-standard-with-typescript: 23.0.0_c9fe9619f50f4e82337a86c3af25e566 + eslint-plugin-import: 2.26.0_eslint@8.27.0 + eslint-plugin-n: 15.5.1_eslint@8.27.0 + eslint-plugin-promise: 6.1.1_eslint@8.27.0 + prettier: 2.7.1 + typescript: 4.8.4 + transitivePeerDependencies: + - supports-color + dev: false + + file:projects/server-view.tgz: + resolution: {integrity: sha512-AH+QA0WQmKB1m8M6hJpR48LeTqwkPPY5BlLBmIe99GAbqjYcmLxZWuNEs/nH74ZO8NbUu/3+stc0ZSvUc20M9w==, tarball: file:projects/server-view.tgz} + name: '@rush-temp/server-view' + version: 0.0.0 + dependencies: + '@rushstack/heft': 0.47.11 + '@types/heft-jest': 1.0.3 + '@types/node': 16.11.68 + '@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464 + '@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4 + eslint: 8.27.0 + eslint-config-standard-with-typescript: 23.0.0_c9fe9619f50f4e82337a86c3af25e566 + eslint-plugin-import: 2.26.0_eslint@8.27.0 + eslint-plugin-n: 15.5.1_eslint@8.27.0 + eslint-plugin-promise: 6.1.1_eslint@8.27.0 + prettier: 2.7.1 + typescript: 4.8.4 + transitivePeerDependencies: + - supports-color + dev: false + file:projects/server-ws.tgz: resolution: {integrity: sha512-Ig+xm6b3UgwJ3LFYPjjo0UUphKxFaoNSgCbXiP+wF5jBTgE6pawBzNoZ+5W3osmBTw6nOOofMezIVbW/Y3OHNA==, tarball: file:projects/server-ws.tgz} name: '@rush-temp/server-ws' diff --git a/dev/prod/package.json b/dev/prod/package.json index d65d932a58..4d50d24a72 100644 --- a/dev/prod/package.json +++ b/dev/prod/package.json @@ -161,6 +161,8 @@ "@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-request-resources": "^0.6.0", + "@hcengineering/server-view": "^0.6.0", + "@hcengineering/server-view-resources": "^0.6.0" } } diff --git a/dev/tool/package.json b/dev/tool/package.json index 1a703a2b59..c6aaa026b8 100644 --- a/dev/tool/package.json +++ b/dev/tool/package.json @@ -105,6 +105,8 @@ "@hcengineering/server-hr-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/rekoni": "^0.6.0", "got": "^11.8.3", "@hcengineering/tags": "^0.6.3", diff --git a/dev/tool/src/__start.ts b/dev/tool/src/__start.ts index db6ea38d01..2ff76b4df0 100644 --- a/dev/tool/src/__start.ts +++ b/dev/tool/src/__start.ts @@ -37,6 +37,7 @@ import { serverTrackerId } from '@hcengineering/server-tracker' import { serverTelegramId } from '@hcengineering/server-telegram' import { serverHrId } from '@hcengineering/server-hr' import { serverRequestId } from '@hcengineering/server-request' +import { serverViewId } from '@hcengineering/server-view' import { addLocation } from '@hcengineering/platform' addLocation(serverAttachmentId, () => import('@hcengineering/server-attachment-resources')) @@ -55,6 +56,7 @@ addLocation(serverGmailId, () => import('@hcengineering/server-gmail-resources') addLocation(serverTelegramId, () => import('@hcengineering/server-telegram-resources')) addLocation(serverHrId, () => import('@hcengineering/server-hr-resources')) addLocation(serverRequestId, () => import('@hcengineering/server-request-resources')) +addLocation(serverViewId, () => import('@hcengineering/server-view-resources')) function prepareTools (): { mongodbUri: string diff --git a/models/all/package.json b/models/all/package.json index 452ed1ebbf..b57fcd9e5a 100644 --- a/models/all/package.json +++ b/models/all/package.json @@ -78,6 +78,7 @@ "@hcengineering/model-bitrix": "^0.6.0", "@hcengineering/model-request": "^0.6.0", "@hcengineering/model-server-request": "^0.6.0", + "@hcengineering/model-server-view": "^0.6.0", "@hcengineering/model-server-openai": "^0.6.0", "@hcengineering/model-server-translate": "^0.6.0" } diff --git a/models/all/src/index.ts b/models/all/src/index.ts index c7c3dd1712..84dac2451a 100644 --- a/models/all/src/index.ts +++ b/models/all/src/index.ts @@ -62,6 +62,7 @@ import { createModel as documentModel } from '@hcengineering/model-document' import { createModel as bitrixModel } from '@hcengineering/model-bitrix' import { createModel as requestModel } from '@hcengineering/model-request' import { createModel as serverRequestModel } from '@hcengineering/model-server-request' +import { createModel as serverViewModel } from '@hcengineering/model-server-view' import { createModel as serverTranslate } from '@hcengineering/model-server-translate' import { createModel as serverOpenAI } from '@hcengineering/model-server-openai' @@ -116,6 +117,7 @@ const builders: [(b: Builder) => void, string][] = [ [serverHrModel, 'server-hr'], [serverNotificationModel, 'server-notification'], [serverRequestModel, 'server-request'], + [serverViewModel, 'server-view'], [automationModel, 'automation'], [serverTranslate, 'translate'], [serverOpenAI, 'openai'] diff --git a/models/server-view/.eslintrc.js b/models/server-view/.eslintrc.js new file mode 100644 index 0000000000..59eb1482fa --- /dev/null +++ b/models/server-view/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/model-rig/profiles/default/config/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/models/server-view/.npmignore b/models/server-view/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/models/server-view/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/models/server-view/config/rig.json b/models/server-view/config/rig.json new file mode 100644 index 0000000000..45672e5d25 --- /dev/null +++ b/models/server-view/config/rig.json @@ -0,0 +1,18 @@ +// The "rig.json" file directs tools to look for their config files in an external package. +// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + + /** + * (Required) The name of the rig package to inherit from. + * It should be an NPM package name with the "-rig" suffix. + */ + "rigPackageName": "@hcengineering/model-rig" + + /** + * (Optional) Selects a config profile from the rig package. The name must consist of + * lowercase alphanumeric words separated by hyphens, for example "sample-profile". + * If omitted, then the "default" profile will be used." + */ + // "rigProfile": "your-profile-name" +} diff --git a/models/server-view/package.json b/models/server-view/package.json new file mode 100644 index 0000000000..87935f3f54 --- /dev/null +++ b/models/server-view/package.json @@ -0,0 +1,34 @@ +{ + "name": "@hcengineering/model-server-view", + "version": "0.6.0", + "main": "lib/index.js", + "author": "Anticrm Platform Contributors", + "license": "EPL-2.0", + "scripts": { + "build": "heft build", + "build:watch": "tsc", + "lint:fix": "eslint --fix src", + "lint": "eslint src", + "format": "prettier --write src && eslint --fix src" + }, + "devDependencies": { + "@hcengineering/model-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^5.41.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.26.0", + "@types/heft-jest": "^1.0.3", + "@typescript-eslint/parser": "^5.41.0", + "eslint-config-standard-with-typescript": "^23.0.0", + "prettier": "^2.7.1", + "@rushstack/heft": "^0.47.9" + }, + "dependencies": { + "@hcengineering/core": "^0.6.20", + "@hcengineering/model": "^0.6.0", + "@hcengineering/platform": "^0.6.8", + "@hcengineering/server-view": "^0.6.0", + "@hcengineering/server-core": "^0.6.1" + } +} diff --git a/models/server-view/src/index.ts b/models/server-view/src/index.ts new file mode 100644 index 0000000000..ccfd65a65f --- /dev/null +++ b/models/server-view/src/index.ts @@ -0,0 +1,25 @@ +// +// Copyright © 2022 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { Builder } from '@hcengineering/model' +import core from '@hcengineering/core' +import serverCore from '@hcengineering/server-core' +import serverView from '@hcengineering/server-view' + +export function createModel (builder: Builder): void { + builder.createDoc(serverCore.class.Trigger, core.space.Model, { + trigger: serverView.trigger.OnCustomAttributeRemove + }) +} diff --git a/models/server-view/tsconfig.json b/models/server-view/tsconfig.json new file mode 100644 index 0000000000..807a92c38c --- /dev/null +++ b/models/server-view/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "./node_modules/@hcengineering/model-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + } +} \ No newline at end of file diff --git a/models/view/src/migration.ts b/models/view/src/migration.ts index 30b0f6038f..c14acb808a 100644 --- a/models/view/src/migration.ts +++ b/models/view/src/migration.ts @@ -13,9 +13,9 @@ // limitations under the License. // -import { Ref } from '@hcengineering/core' +import core, { AnyAttribute, DOMAIN_TX, Ref, TxCreateDoc, TxCUD, TxProcessor, TxRemoveDoc } from '@hcengineering/core' import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@hcengineering/model' -import { FilteredView, Viewlet, ViewletPreference } from '@hcengineering/view' +import { BuildModelKey, FilteredView, Viewlet, ViewletPreference } from '@hcengineering/view' import { DOMAIN_PREFERENCE } from '@hcengineering/preference' import view from './plugin' @@ -78,10 +78,78 @@ async function migrateSavedFilters (client: MigrationClient): Promise { } } +async function fixViewletPreferenceRemovedAttributes (client: MigrationClient): Promise { + const removeTxes = await client.find>(DOMAIN_TX, { + _class: core.class.TxRemoveDoc, + objectClass: core.class.Attribute + }) + for (const removeTx of removeTxes) { + const createTx = ( + await client.find>(DOMAIN_TX, { + _class: core.class.TxCreateDoc, + objectId: removeTx.objectId + }) + )[0] + const key = createTx.attributes.name + await client.update( + DOMAIN_PREFERENCE, + { config: key }, + { + $pull: { config: key } + } + ) + } +} + +async function fixPreferenceObjectKey (client: MigrationClient): Promise { + const preferences = await client.find(DOMAIN_PREFERENCE, { _class: view.class.ViewletPreference }) + for (const preference of preferences) { + let index = preference.config.indexOf('') + if (index === -1) continue + index = preference.config.indexOf('', index + 1) + if (index === -1) continue + const descTxes = await client.find>(DOMAIN_TX, { objectId: preference.attachedTo }) + const desc = TxProcessor.buildDoc2Doc(descTxes) + if (desc === undefined) continue + const targets = desc.config.filter((p) => (p as BuildModelKey).key === '') + let i = 0 + while (index !== -1) { + const target = targets[i++] + if (target !== undefined) { + await client.update( + DOMAIN_PREFERENCE, + { + _id: preference._id + }, + { $set: { [`config.${index}`]: target } } + ) + } else { + await client.update( + DOMAIN_PREFERENCE, + { + _id: preference._id + }, + { $unset: { [`config.${index}`]: 1 } } + ) + await client.update( + DOMAIN_PREFERENCE, + { + _id: preference._id + }, + { $pull: { config: null } } + ) + } + index = preference.config.indexOf('', index + 1) + } + } +} + export const viewOperation: MigrateOperation = { async migrate (client: MigrationClient): Promise { await migrateViewletPreference(client) await migrateSavedFilters(client) + await fixViewletPreferenceRemovedAttributes(client) + await fixPreferenceObjectKey(client) }, async upgrade (client: MigrationUpgradeClient): Promise {} } diff --git a/packages/presentation/src/utils.ts b/packages/presentation/src/utils.ts index a0c6681824..4ea811e239 100644 --- a/packages/presentation/src/utils.ts +++ b/packages/presentation/src/utils.ts @@ -216,10 +216,10 @@ export function getAttributePresenterClass ( attribute: AnyAttribute ): { attrClass: Ref>, category: AttributeCategory } { let attrClass = attribute.type._class - let category: AttributeCategory = 'object' + let category: AttributeCategory = 'attribute' if (hierarchy.isDerived(attrClass, core.class.RefTo)) { attrClass = (attribute.type as RefTo).to - category = 'attribute' + category = 'object' } if (hierarchy.isDerived(attrClass, core.class.TypeMarkup)) { category = 'inplace' diff --git a/plugins/setting-assets/lang/ru.json b/plugins/setting-assets/lang/ru.json index b41151f18e..399f71214b 100644 --- a/plugins/setting-assets/lang/ru.json +++ b/plugins/setting-assets/lang/ru.json @@ -64,8 +64,8 @@ "OldNames": "Предыдушие значения", "NewClassName": "Введите новое имя класса или выберете прошлое значение...", - "ShowAttribute": "Hide", - "HideAttribute": "Show", + "ShowAttribute": "Показать", + "HideAttribute": "Спрятать", "Visibility": "Видимость", "Hidden": "Спрятанный", "Configure": "Настроить..." diff --git a/plugins/view-resources/src/components/ViewletSetting.svelte b/plugins/view-resources/src/components/ViewletSetting.svelte index 4544e84545..1d42b4a2b9 100644 --- a/plugins/view-resources/src/components/ViewletSetting.svelte +++ b/plugins/view-resources/src/components/ViewletSetting.svelte @@ -18,7 +18,7 @@ import preferencePlugin from '@hcengineering/preference' import presentation, { Card, createQuery, getAttributePresenterClass, getClient } from '@hcengineering/presentation' import { Button, getPlatformColorForText, ToggleButton } from '@hcengineering/ui' - import { Viewlet, ViewletPreference } from '@hcengineering/view' + import { BuildModelKey, Viewlet, ViewletPreference } from '@hcengineering/view' import { deepEqual } from 'fast-equals' import { createEventDispatcher } from 'svelte' import view from '../plugin' @@ -53,7 +53,7 @@ interface AttributeConfig { enabled: boolean label: IntlString - value: string + value: string | BuildModelKey _class: Ref> } @@ -83,16 +83,12 @@ }) } } else { - if (param.key.length === 0) { - result.push(getObjectConfig(viewlet.attachTo, param.key)) - } else { - result.push({ - value: param.key, - label: param.label ?? getKeyLabel(client, viewlet.attachTo, param.key, lookup), - enabled: true, - _class: viewlet.attachTo - }) - } + result.push({ + value: param, + label: param.label as IntlString, + enabled: true, + _class: viewlet.attachTo + }) } } return result diff --git a/pods/server/package.json b/pods/server/package.json index 17ff55d368..758a9364e0 100644 --- a/pods/server/package.json +++ b/pods/server/package.json @@ -77,6 +77,8 @@ "@hcengineering/server-hr-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-token": "^0.6.0", "@hcengineering/middleware": "^0.6.0", "@hcengineering/minio": "^0.6.0", diff --git a/pods/server/src/server.ts b/pods/server/src/server.ts index d94b12d299..91052200f7 100644 --- a/pods/server/src/server.ts +++ b/pods/server/src/server.ts @@ -63,6 +63,7 @@ import { serverLeadId } from '@hcengineering/server-lead' import { serverNotificationId } from '@hcengineering/server-notification' import { serverRecruitId } from '@hcengineering/server-recruit' import { serverRequestId } from '@hcengineering/server-request' +import { serverViewId } from '@hcengineering/server-view' import { serverSettingId } from '@hcengineering/server-setting' import { serverTagsId } from '@hcengineering/server-tags' import { serverTaskId } from '@hcengineering/server-task' @@ -179,6 +180,7 @@ export function start ( addLocation(serverGmailId, () => import('@hcengineering/server-gmail-resources')) addLocation(serverTelegramId, () => import('@hcengineering/server-telegram-resources')) addLocation(serverRequestId, () => import('@hcengineering/server-request-resources')) + addLocation(serverViewId, () => import('@hcengineering/server-view-resources')) addLocation(serverHrId, () => import('@hcengineering/server-hr-resources')) addLocation(openAIId, () => Promise.resolve({ default: openAIPluginImpl })) diff --git a/rush.json b/rush.json index cb7a475b07..7c699c043a 100644 --- a/rush.json +++ b/rush.json @@ -1489,5 +1489,20 @@ "projectFolder": "models/server-openai", "shouldPublish": true }, + { + "packageName": "@hcengineering/server-view", + "projectFolder": "server-plugins/view", + "shouldPublish": true + }, + { + "packageName": "@hcengineering/model-server-view", + "projectFolder": "models/server-view", + "shouldPublish": true + }, + { + "packageName": "@hcengineering/server-view-resources", + "projectFolder": "server-plugins/view-resources", + "shouldPublish": true + }, ] } diff --git a/server-plugins/view-resources/.eslintrc.js b/server-plugins/view-resources/.eslintrc.js new file mode 100644 index 0000000000..7f7cebe58b --- /dev/null +++ b/server-plugins/view-resources/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/config/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/server-plugins/view-resources/.npmignore b/server-plugins/view-resources/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/server-plugins/view-resources/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/server-plugins/view-resources/config/rig.json b/server-plugins/view-resources/config/rig.json new file mode 100644 index 0000000000..2fdc07ba20 --- /dev/null +++ b/server-plugins/view-resources/config/rig.json @@ -0,0 +1,18 @@ +// The "rig.json" file directs tools to look for their config files in an external package. +// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + + /** + * (Required) The name of the rig package to inherit from. + * It should be an NPM package name with the "-rig" suffix. + */ + "rigPackageName": "@hcengineering/platform-rig" + + /** + * (Optional) Selects a config profile from the rig package. The name must consist of + * lowercase alphanumeric words separated by hyphens, for example "sample-profile". + * If omitted, then the "default" profile will be used." + */ + // "rigProfile": "your-profile-name" +} diff --git a/server-plugins/view-resources/package.json b/server-plugins/view-resources/package.json new file mode 100644 index 0000000000..75aecedd55 --- /dev/null +++ b/server-plugins/view-resources/package.json @@ -0,0 +1,35 @@ +{ + "name": "@hcengineering/server-view-resources", + "version": "0.6.0", + "main": "lib/index.js", + "author": "Anticrm Platform Contributors", + "license": "EPL-2.0", + "scripts": { + "build": "heft build", + "build:watch": "tsc", + "lint:fix": "eslint --fix src", + "lint": "eslint src", + "format": "prettier --write src && eslint --fix src" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@types/heft-jest": "^1.0.3", + "@typescript-eslint/eslint-plugin": "^5.41.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.26.0", + "@typescript-eslint/parser": "^5.41.0", + "eslint-config-standard-with-typescript": "^23.0.0", + "prettier": "^2.7.1", + "@rushstack/heft": "^0.47.9", + "typescript": "^4.3.5" + }, + "dependencies": { + "@hcengineering/core": "^0.6.20", + "@hcengineering/platform": "^0.6.8", + "@hcengineering/server-core": "^0.6.1", + "@hcengineering/server-view": "^0.6.0", + "@hcengineering/view": "^0.6.2" + } +} diff --git a/server-plugins/view-resources/src/index.ts b/server-plugins/view-resources/src/index.ts new file mode 100644 index 0000000000..51c30800a5 --- /dev/null +++ b/server-plugins/view-resources/src/index.ts @@ -0,0 +1,57 @@ +// +// Copyright © 2022 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import core, { AnyAttribute, Hierarchy, Tx, TxCUD, TxProcessor, TxRemoveDoc } from '@hcengineering/core' +import type { TriggerControl } from '@hcengineering/server-core' +import view from '@hcengineering/view' + +/** + * @public + */ +export async function OnCustomAttributeRemove (tx: Tx, control: TriggerControl): Promise { + const hierarchy = control.hierarchy + const ptx = tx as TxRemoveDoc + if (!checkTx(ptx, hierarchy)) return [] + const txes = await control.findAll>(core.class.TxCUD, { objectId: ptx.objectId }) + const attribute = TxProcessor.buildDoc2Doc(txes) + if (attribute === undefined) return [] + const preferences = await control.findAll(view.class.ViewletPreference, { config: attribute.name }) + const res: Tx[] = [] + for (const preference of preferences) { + const tx = control.txFactory.createTxUpdateDoc(preference._class, preference.space, preference._id, { + $pull: { config: attribute.name } + }) + res.push(tx) + } + return res +} + +function checkTx (ptx: TxRemoveDoc, hierarchy: Hierarchy): boolean { + if (ptx._class !== core.class.TxRemoveDoc) { + return false + } + + if (!hierarchy.isDerived(ptx.objectClass, core.class.Attribute)) { + return false + } + return true +} + +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export default async () => ({ + trigger: { + OnCustomAttributeRemove + } +}) diff --git a/server-plugins/view-resources/tsconfig.json b/server-plugins/view-resources/tsconfig.json new file mode 100644 index 0000000000..9b47eded03 --- /dev/null +++ b/server-plugins/view-resources/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + } +} \ No newline at end of file diff --git a/server-plugins/view/.eslintrc.js b/server-plugins/view/.eslintrc.js new file mode 100644 index 0000000000..7f7cebe58b --- /dev/null +++ b/server-plugins/view/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/config/eslint.config.json'], + parserOptions: { + tsconfigRootDir: __dirname, + project: './tsconfig.json' + } +} diff --git a/server-plugins/view/.npmignore b/server-plugins/view/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/server-plugins/view/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/server-plugins/view/config/rig.json b/server-plugins/view/config/rig.json new file mode 100644 index 0000000000..2fdc07ba20 --- /dev/null +++ b/server-plugins/view/config/rig.json @@ -0,0 +1,18 @@ +// The "rig.json" file directs tools to look for their config files in an external package. +// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package +{ + "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", + + /** + * (Required) The name of the rig package to inherit from. + * It should be an NPM package name with the "-rig" suffix. + */ + "rigPackageName": "@hcengineering/platform-rig" + + /** + * (Optional) Selects a config profile from the rig package. The name must consist of + * lowercase alphanumeric words separated by hyphens, for example "sample-profile". + * If omitted, then the "default" profile will be used." + */ + // "rigProfile": "your-profile-name" +} diff --git a/server-plugins/view/package.json b/server-plugins/view/package.json new file mode 100644 index 0000000000..78a72f01bb --- /dev/null +++ b/server-plugins/view/package.json @@ -0,0 +1,34 @@ +{ + "name": "@hcengineering/server-view", + "version": "0.6.0", + "main": "lib/index.js", + "author": "Anticrm Platform Contributors", + "license": "EPL-2.0", + "scripts": { + "build": "heft build", + "build:watch": "tsc", + "lint:fix": "eslint --fix src", + "lint": "eslint src", + "format": "prettier --write src && eslint --fix src" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@types/heft-jest": "^1.0.3", + "@types/node": "~16.11.12", + "@typescript-eslint/eslint-plugin": "^5.41.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-n": "^15.4.0", + "eslint": "^8.26.0", + "@typescript-eslint/parser": "^5.41.0", + "eslint-config-standard-with-typescript": "^23.0.0", + "prettier": "^2.7.1", + "@rushstack/heft": "^0.47.9", + "typescript": "^4.3.5" + }, + "dependencies": { + "@hcengineering/server-notification": "^0.6.0", + "@hcengineering/platform": "^0.6.8", + "@hcengineering/server-core": "^0.6.1" + } +} diff --git a/server-plugins/view/src/index.ts b/server-plugins/view/src/index.ts new file mode 100644 index 0000000000..20ce2fa3b4 --- /dev/null +++ b/server-plugins/view/src/index.ts @@ -0,0 +1,32 @@ +// +// Copyright © 2022 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import type { Plugin, Resource } from '@hcengineering/platform' +import { TriggerFunc } from '@hcengineering/server-core' +import { plugin } from '@hcengineering/platform' + +/** + * @public + */ +export const serverViewId = 'server-view' as Plugin + +/** + * @public + */ +export default plugin(serverViewId, { + trigger: { + OnCustomAttributeRemove: '' as Resource + } +}) diff --git a/server-plugins/view/tsconfig.json b/server-plugins/view/tsconfig.json new file mode 100644 index 0000000000..b88f95eba6 --- /dev/null +++ b/server-plugins/view/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json", + + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "esModuleInterop": true + } +} \ No newline at end of file