diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index b118d34aa7..4e18bf051b 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -545,6 +545,9 @@ dependencies: '@rush-temp/model-templates': specifier: file:./projects/model-templates.tgz version: file:projects/model-templates.tgz + '@rush-temp/model-test-management': + specifier: file:./projects/model-test-management.tgz + version: file:projects/model-test-management.tgz '@rush-temp/model-text-editor': specifier: file:./projects/model-text-editor.tgz version: file:projects/model-text-editor.tgz @@ -1022,6 +1025,15 @@ dependencies: '@rush-temp/templates-resources': specifier: file:./projects/templates-resources.tgz version: file:projects/templates-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/test-management': + specifier: file:./projects/test-management.tgz + version: file:projects/test-management.tgz(@types/node@20.11.19)(esbuild@0.20.1)(ts-node@10.9.2) + '@rush-temp/test-management-assets': + specifier: file:./projects/test-management-assets.tgz + version: file:projects/test-management-assets.tgz(esbuild@0.20.1)(ts-node@10.9.2) + '@rush-temp/test-management-resources': + specifier: file:./projects/test-management-resources.tgz + version: file:projects/test-management-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/tests-sanity': specifier: file:./projects/tests-sanity.tgz version: file:projects/tests-sanity.tgz @@ -22727,7 +22739,7 @@ packages: dev: false file:projects/desktop.tgz(bufferutil@4.0.8)(sass@1.71.1)(utf-8-validate@6.0.4): - resolution: {integrity: sha512-VjzxhhavCElN2Ak6+7CforJ3IJK0/iTE6crFhcRZrbq4RajWlGEHpD/o7O3mun0xepqA0QxpHCkTIO6SQdPsOg==, tarball: file:projects/desktop.tgz} + resolution: {integrity: sha512-rjywmlFY/JneloAn6/L8+zLke89G1qy9ROO+fB2hJwYZDK0JGaN0CE68Sq8iZX6fJ+sAIGW6IsbbfpsvhmhUag==, tarball: file:projects/desktop.tgz} id: file:projects/desktop.tgz name: '@rush-temp/desktop' version: 0.0.0 @@ -24471,7 +24483,7 @@ packages: dev: false file:projects/model-all.tgz: - resolution: {integrity: sha512-lZSE4CGfPJX/cTsbqnSoz/ge496Cwl3zeRFHM2wrpgfCFyeCNp00xpRv62LPGe38dvHo/IIzy+Uu0RSVPHUOPw==, tarball: file:projects/model-all.tgz} + resolution: {integrity: sha512-Fxv8P/cfFWJfFli1C70fOej/quvHGGyzJBLpbEixsPV2F+pqX53mwpTzAPqVkHLFVwbRkpnociSpaJQYyx0Beg==, tarball: file:projects/model-all.tgz} name: '@rush-temp/model-all' version: 0.0.0 dependencies: @@ -25719,6 +25731,24 @@ packages: - supports-color dev: false + file:projects/model-test-management.tgz: + resolution: {integrity: sha512-p0y76Msm6v7Zg8KlvMDiWV3BKCDEw8KjV9sUwC+wkMvKnJ4tOtErd+OdnJFKOyGbtX6yX8rCSp6NIJwqmMmhSA==, tarball: file:projects/model-test-management.tgz} + name: '@rush-temp/model-test-management' + version: 0.0.0 + dependencies: + '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.56.0)(typescript@5.6.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.2) + 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.6.2) + 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.6.2 + transitivePeerDependencies: + - supports-color + dev: false + file:projects/model-text-editor.tgz: resolution: {integrity: sha512-z1TlVHF8VxcMeChSZ70ZGJsKdGSKisnpnPGuLmp2yYS30ckD5ohoj4KeqgbKu+qT+72FYSg4COXFoAYnszgfoA==, tarball: file:projects/model-text-editor.tgz} name: '@rush-temp/model-text-editor' @@ -27488,7 +27518,7 @@ packages: dev: false file:projects/prod.tgz(bufferutil@4.0.8)(sass@1.71.1)(ts-node@10.9.2)(utf-8-validate@6.0.4): - resolution: {integrity: sha512-LpzXVVxqqH4eEF3U7B9uOy/zBFWAZ+FGeGqIBCo9N7UzWxndKf7LZx+eYJQ8gsg5aVoqlGAbXjZJHHSVERGeJQ==, tarball: file:projects/prod.tgz} + resolution: {integrity: sha512-vNHiwvJN+OiPr+lWDdxC3+YB6vZPF0QHYXMXrmHcagQH5vEfVzRPmL9F8pTnx/MHPvAlDt4DqgQls77F8LFYgg==, tarball: file:projects/prod.tgz} id: file:projects/prod.tgz name: '@rush-temp/prod' version: 0.0.0 @@ -29382,7 +29412,7 @@ packages: dev: false file:projects/server-indexer.tgz(esbuild@0.20.1)(ts-node@10.9.2): - resolution: {integrity: sha512-H/iX6BGnUy04J35NoefNnWyoCqEd5RFve5SMXioIuA4tWqglHcAz8JqyPPLlfN+onrsh4Pz0tTVRV6lOZXSXWw==, tarball: file:projects/server-indexer.tgz} + resolution: {integrity: sha512-X0K8LN7D/inN8B9B+/ERJTAm1l0gQ7fA9nOdMMVUHEVZqmq6WoiSZ+vPxdY/dx+MQlYFTcPumxLgZiVCZET4Og==, tarball: file:projects/server-indexer.tgz} id: file:projects/server-indexer.tgz name: '@rush-temp/server-indexer' version: 0.0.0 @@ -31256,6 +31286,113 @@ packages: - ts-node dev: false + file:projects/test-management-assets.tgz(esbuild@0.20.1)(ts-node@10.9.2): + resolution: {integrity: sha512-5goSfMWyruB2GJwVYnn8e9YYJW523dDrcME75Og3+yem8W+yUcteJ+Sy2qgMNjCzC6ADzxCM5TIHItnCpH0gjQ==, tarball: file:projects/test-management-assets.tgz} + id: file:projects/test-management-assets.tgz + name: '@rush-temp/test-management-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.6.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.2) + 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.6.2) + 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 + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.6.2) + typescript: 5.6.2 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + dev: false + + file:projects/test-management-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): + resolution: {integrity: sha512-o+axSz7dIMDinwB3h8Ntr1pP35PGsUtKtTUvEqJFQ1lA+KQdTJ9akLrijzp9T6xRSdTPa6WNG6yjtqM8yhC70w==, tarball: file:projects/test-management-resources.tgz} + id: file:projects/test-management-resources.tgz + name: '@rush-temp/test-management-resources' + 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.6.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.2) + 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.6.2) + eslint-plugin-import: 2.29.1(eslint@8.56.0) + eslint-plugin-n: 15.7.0(eslint@8.56.0) + eslint-plugin-promise: 6.1.1(eslint@8.56.0) + eslint-plugin-svelte: 2.35.1(eslint@8.56.0)(svelte@4.2.19)(ts-node@10.9.2) + fast-equals: 5.0.1 + jest: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: 3.2.5 + prettier-plugin-svelte: 3.2.2(prettier@3.2.5)(svelte@4.2.19) + sass: 1.71.1 + svelte: 4.2.19 + svelte-check: 3.6.9(postcss-load-config@4.0.2)(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.19) + svelte-eslint-parser: 0.33.1(svelte@4.2.19) + svelte-loader: 3.2.0(svelte@4.2.19) + svelte-preprocess: 5.1.3(postcss-load-config@4.0.2)(postcss@8.4.35)(sass@1.71.1)(svelte@4.2.19)(typescript@5.6.2) + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.6.2) + typescript: 5.6.2 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - coffeescript + - esbuild + - less + - node-notifier + - postcss + - postcss-load-config + - pug + - stylus + - sugarss + - supports-color + - ts-node + dev: false + + file:projects/test-management.tgz(@types/node@20.11.19)(esbuild@0.20.1)(ts-node@10.9.2): + resolution: {integrity: sha512-zLxjXJwufmBoWJS5xoCGxG9uybC/T7UtJ+g4PlSnDv16aGSPDbnybLtQ0uorYvlOESpcSgQGrVLCgOhIB90tfw==, tarball: file:projects/test-management.tgz} + id: file:projects/test-management.tgz + name: '@rush-temp/test-management' + 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.6.2) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.6.2) + 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.6.2) + 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) + lexorank: 1.0.5 + prettier: 3.2.5 + ts-jest: 29.1.2(esbuild@0.20.1)(jest@29.7.0)(typescript@5.6.2) + typescript: 5.6.2 + transitivePeerDependencies: + - '@babel/core' + - '@jest/types' + - '@types/node' + - babel-jest + - babel-plugin-macros + - esbuild + - node-notifier + - supports-color + - ts-node + dev: false + file:projects/tests-sanity.tgz: resolution: {integrity: sha512-noV3nlBP0OvM6i4C5YUevkhltHxG/2bct4pusP3O3AEQ7Za+A4qwzpsE08pHfA9f9pedEG677GE4EmG9x61rVQ==, tarball: file:projects/tests-sanity.tgz} name: '@rush-temp/tests-sanity' @@ -31748,7 +31885,7 @@ packages: dev: false file:projects/tracker-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): - resolution: {integrity: sha512-6wsyMyxPpL8OKwTKistPKvRxkmmptqXJwxFZ5VOOlGuEwqXFYIPYZNR6taZd33fq1Y97L+vKeP65rWmXhbRIdQ==, tarball: file:projects/tracker-resources.tgz} + resolution: {integrity: sha512-k1Lw3hvnvA+K22hLtdZKz4+ZQbk451p8bQL0RIHZ/yS/dIBLlBpBUU279YAqH2zxlmlFt1+C1WsTsrrPRdfx7A==, tarball: file:projects/tracker-resources.tgz} id: file:projects/tracker-resources.tgz name: '@rush-temp/tracker-resources' version: 0.0.0 diff --git a/desktop/package.json b/desktop/package.json index fbe76ee9ee..8f9e667d91 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -204,6 +204,9 @@ "@hcengineering/analytics-collector-resources": "^0.6.0", "@hcengineering/ai-bot": "^0.6.0", "@hcengineering/ai-bot-resources": "^0.6.0", + "@hcengineering/test-management": "^0.6.0", + "@hcengineering/test-management-assets": "^0.6.0", + "@hcengineering/test-management-resources": "^0.6.0", "electron-squirrel-startup": "~1.0.0", "dotenv": "~16.0.0", "electron-context-menu": "^4.0.4", diff --git a/desktop/src/ui/platform.ts b/desktop/src/ui/platform.ts index 74aecd76d9..2615151bfd 100644 --- a/desktop/src/ui/platform.ts +++ b/desktop/src/ui/platform.ts @@ -53,6 +53,7 @@ import { questionsId } from '@hcengineering/questions' import { trainingId } from '@hcengineering/training' import { documentsId } from '@hcengineering/controlled-documents' import aiBot, { aiBotId } from '@hcengineering/ai-bot' +import { testManagementId } from '@hcengineering/test-management' import '@hcengineering/activity-assets' import '@hcengineering/attachment-assets' @@ -94,6 +95,7 @@ import '@hcengineering/products-assets' import '@hcengineering/controlled-documents-assets' import '@hcengineering/analytics-collector-assets' import '@hcengineering/text-editor-assets' +import '@hcengineering/test-management-assets' import { coreId } from '@hcengineering/core' import presentation, { parsePreviewConfig, parseUploadConfig, presentationId } from '@hcengineering/presentation' @@ -185,6 +187,7 @@ function configureI18n (): void { addStringsLoader(loveId, async (lang: string) => await import(`@hcengineering/love-assets/lang/${lang}.json`)) addStringsLoader(printId, async (lang: string) => await import(`@hcengineering/print-assets/lang/${lang}.json`)) addStringsLoader(analyticsCollectorId, async (lang: string) => await import(`@hcengineering/analytics-collector-assets/lang/${lang}.json`)) + addStringsLoader(testManagementId, async (lang: string) => await import(`@hcengineering/test-management-assets/lang/${lang}.json`)) } export async function configurePlatform (): Promise { @@ -306,6 +309,7 @@ export async function configurePlatform (): Promise { addLocation(loveId, () => import(/* webpackChunkName: "love" */ '@hcengineering/love-resources')) addLocation(printId, () => import(/* webpackChunkName: "print" */ '@hcengineering/print-resources')) addLocation(textEditorId, () => import(/* webpackChunkName: "text-editor" */ '@hcengineering/text-editor-resources')) + addLocation(testManagementId, () => import(/* webpackChunkName: "test-management" */ '@hcengineering/test-management-resources')) setMetadata(client.metadata.FilterModel, 'ui') setMetadata(client.metadata.ExtraPlugins, ['preference' as Plugin]) diff --git a/dev/prod/package.json b/dev/prod/package.json index 2b7474a8e7..32a0058b94 100644 --- a/dev/prod/package.json +++ b/dev/prod/package.json @@ -233,6 +233,9 @@ "@hcengineering/products-resources": "^0.1.0", "@hcengineering/ai-bot": "^0.6.0", "@hcengineering/ai-bot-resources": "^0.6.0", + "@hcengineering/test-management": "^0.6.0", + "@hcengineering/test-management-assets": "^0.6.0", + "@hcengineering/test-management-resources": "^0.6.0", "@sentry/svelte": "~7.101.0", "posthog-js": "~1.122.0" } diff --git a/dev/prod/src/platform.ts b/dev/prod/src/platform.ts index 047464e2d9..81852db511 100644 --- a/dev/prod/src/platform.ts +++ b/dev/prod/src/platform.ts @@ -60,6 +60,7 @@ import textEditor, { textEditorId } from '@hcengineering/text-editor' import analyticsCollector, {analyticsCollectorId} from '@hcengineering/analytics-collector' import { uploaderId } from '@hcengineering/uploader' import aiBot, { aiBotId } from '@hcengineering/ai-bot' +import { testManagementId } from '@hcengineering/test-management' import { bitrixId } from '@hcengineering/bitrix' @@ -103,6 +104,7 @@ import '@hcengineering/controlled-documents-assets' import '@hcengineering/analytics-collector-assets' import '@hcengineering/text-editor-assets' import '@hcengineering/uploader-assets' +import '@hcengineering/test-management-assets' import github, { githubId } from '@hcengineering/github' import '@hcengineering/github-assets' @@ -231,6 +233,7 @@ function configureI18n(): void { addStringsLoader(loveId, async (lang: string) => await import(`@hcengineering/love-assets/lang/${lang}.json`)) addStringsLoader(printId, async (lang: string) => await import(`@hcengineering/print-assets/lang/${lang}.json`)) addStringsLoader(analyticsCollectorId, async (lang: string) => await import(`@hcengineering/analytics-collector-assets/lang/${lang}.json`)) + addStringsLoader(testManagementId, async (lang: string) => await import(`@hcengineering/test-management-assets/lang/${lang}.json`)) } export async function configurePlatform() { @@ -399,6 +402,7 @@ export async function configurePlatform() { addLocation(printId, () => import(/* webpackChunkName: "print" */ '@hcengineering/print-resources')) addLocation(textEditorId, () => import(/* webpackChunkName: "text-editor" */ '@hcengineering/text-editor-resources')) addLocation(uploaderId, () => import(/* webpackChunkName: "uploader" */ '@hcengineering/uploader-resources')) + addLocation(testManagementId, () => import(/* webpackChunkName: "test-management" */ '@hcengineering/test-management-resources')) setMetadata(client.metadata.FilterModel, 'ui') setMetadata(client.metadata.ExtraPlugins, ['preference' as Plugin]) diff --git a/models/all/package.json b/models/all/package.json index 9102565911..85c6f9931e 100644 --- a/models/all/package.json +++ b/models/all/package.json @@ -110,6 +110,7 @@ "@hcengineering/model-analytics-collector": "^0.6.0", "@hcengineering/model-server-ai-bot": "^0.6.0", "@hcengineering/model-ai-bot": "^0.6.0", - "@hcengineering/model-server-fulltext": "^0.6.0" + "@hcengineering/model-server-fulltext": "^0.6.0", + "@hcengineering/model-test-management": "^0.6.0" } } diff --git a/models/all/src/index.ts b/models/all/src/index.ts index 0563d6749f..5f0d7ea844 100644 --- a/models/all/src/index.ts +++ b/models/all/src/index.ts @@ -95,6 +95,11 @@ import documents, { documentsId, createModel as documentsModel } from '@hcengine import products, { productsId, createModel as productsModel } from '@hcengineering/model-products' import { serverProductsId, createModel as serverProductsModel } from '@hcengineering/model-server-products' import { serverTrainingId, createModel as serverTrainingModel } from '@hcengineering/model-server-training' +import testManagement, { + testManagementId, + createModel as testManagementModel +} from '@hcengineering/model-test-management' + import { serverDocumentsId, createModel as serverDocumentsModel @@ -404,6 +409,17 @@ export default function buildModel (enabled: string[] = ['*'], disabled: string[ classFilter: defaultFilter } ], + [ + testManagementModel, + testManagementId, + { + label: testManagement.string.ConfigLabel, + description: testManagement.string.ConfigDescription, + enabled: false, + beta: false, + classFilter: defaultFilter + } + ], [serverCoreModel, serverCoreId], [serverAttachmentModel, serverAttachmentId], diff --git a/models/all/src/migration.ts b/models/all/src/migration.ts index 4366401105..da2ae3e0a4 100644 --- a/models/all/src/migration.ts +++ b/models/all/src/migration.ts @@ -52,6 +52,7 @@ import { productsOperation } from '@hcengineering/model-products' import { requestOperation } from '@hcengineering/model-request' import { analyticsCollectorOperation } from '@hcengineering/model-analytics-collector' import { workbenchOperation } from '@hcengineering/model-workbench' +import { testManagementOperation } from '@hcengineering/model-test-management' export const migrateOperations: [string, MigrateOperation][] = [ ['core', coreOperation], @@ -92,5 +93,6 @@ export const migrateOperations: [string, MigrateOperation][] = [ // We should call notification migration after activityServer and chunter ['notification', notificationOperation], ['analyticsCollector', analyticsCollectorOperation], - ['workbench', workbenchOperation] + ['workbench', workbenchOperation], + ['testManagement', testManagementOperation] ] diff --git a/models/test-management/.eslintrc.js b/models/test-management/.eslintrc.js new file mode 100644 index 0000000000..c1cf82cba0 --- /dev/null +++ b/models/test-management/.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/test-management/.npmignore b/models/test-management/.npmignore new file mode 100644 index 0000000000..e3ec093c38 --- /dev/null +++ b/models/test-management/.npmignore @@ -0,0 +1,4 @@ +* +!/lib/** +!CHANGELOG.md +/lib/**/__tests__/ diff --git a/models/test-management/config/rig.json b/models/test-management/config/rig.json new file mode 100644 index 0000000000..2f6be36605 --- /dev/null +++ b/models/test-management/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/test-management/package.json b/models/test-management/package.json new file mode 100644 index 0000000000..3607dcccd8 --- /dev/null +++ b/models/test-management/package.json @@ -0,0 +1,59 @@ +{ + "name": "@hcengineering/model-test-management", + "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/attachment": "^0.6.14", + "@hcengineering/activity": "^0.6.0", + "@hcengineering/chunter": "^0.6.20", + "@hcengineering/contact": "^0.6.24", + "@hcengineering/core": "^0.6.32", + "@hcengineering/model": "^0.6.11", + "@hcengineering/model-attachment": "^0.6.0", + "@hcengineering/model-contact": "^0.6.1", + "@hcengineering/model-core": "^0.6.0", + "@hcengineering/model-notification": "^0.6.0", + "@hcengineering/model-presentation": "^0.6.0", + "@hcengineering/model-print": "^0.6.0", + "@hcengineering/model-tracker": "^0.6.0", + "@hcengineering/model-view": "^0.6.0", + "@hcengineering/model-workbench": "^0.6.1", + "@hcengineering/model-activity": "^0.6.0", + "@hcengineering/notification": "^0.6.23", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/setting": "^0.6.17", + "@hcengineering/tags": "^0.6.16", + "@hcengineering/time": "^0.6.0", + "@hcengineering/test-management": "^0.6.0", + "@hcengineering/test-management-resources": "^0.6.0", + "@hcengineering/ui": "^0.6.15", + "@hcengineering/view": "^0.6.13", + "@hcengineering/workbench": "^0.6.16", + "@hcengineering/model-preference": "^0.6.0" + } +} diff --git a/models/test-management/src/defaultTypes.ts b/models/test-management/src/defaultTypes.ts new file mode 100644 index 0000000000..3495aff78a --- /dev/null +++ b/models/test-management/src/defaultTypes.ts @@ -0,0 +1,51 @@ +// +// Copyright © 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 Builder } from '@hcengineering/model' +import core from '@hcengineering/model-core' + +import { TDefaultProjectTypeData } from './types' +import testManagement from './plugin' + +export function defineDefaultSpace (builder: Builder): void { + defineDefaultProject(builder) +} + +function defineDefaultProject (builder: Builder): void { + builder.createModel(TDefaultProjectTypeData) + + builder.createDoc( + core.class.SpaceTypeDescriptor, + core.space.Model, + { + name: testManagement.string.TestProject, + description: testManagement.string.FullDescription, + icon: testManagement.icon.TestProject, + baseClass: testManagement.class.TestProject, + availablePermissions: [ + core.permission.UpdateSpace, + core.permission.ArchiveSpace, + core.permission.ForbidDeleteObject + ] + }, + testManagement.descriptors.ProjectType + ) + + builder.createDoc(core.class.SpaceType, core.space.Model, { + name: 'Default project type', + descriptor: testManagement.descriptors.ProjectType, + roles: 0, + targetClass: testManagement.mixin.DefaultProjectTypeData + }) +} diff --git a/models/test-management/src/index.ts b/models/test-management/src/index.ts new file mode 100644 index 0000000000..6b3a4dac7c --- /dev/null +++ b/models/test-management/src/index.ts @@ -0,0 +1,422 @@ +// +// Copyright © 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 activity from '@hcengineering/activity' +import chunter from '@hcengineering/chunter' +import core from '@hcengineering/model-core' +import { SortingOrder } from '@hcengineering/core' + +import { type Builder } from '@hcengineering/model' +import view, { createAction } from '@hcengineering/model-view' +import workbench from '@hcengineering/model-workbench' +import print from '@hcengineering/model-print' +import tracker from '@hcengineering/model-tracker' +import { type ViewOptionsModel } from '@hcengineering/view' + +import { testManagementId } from '@hcengineering/test-management' + +import { + DOMAIN_TEST_MANAGEMENT, + TTypeTestCaseType, + TTypeTestCasePriority, + TTypeTestCaseStatus, + TTestProject, + TTestSuite, + TTestCase, + TDefaultProjectTypeData, + TTestRun, + TTypeTestRunResult, + TTestRunItem +} from './types' + +import testManagement from './plugin' +import { definePresenters } from './presenters' + +export { testManagementId } from '@hcengineering/test-management/src/index' + +function defineApplication (builder: Builder): void { + builder.createDoc( + workbench.class.Application, + core.space.Model, + { + label: testManagement.string.TestManagementApplication, + icon: testManagement.icon.TestManagementApplication, + alias: testManagementId, + hidden: false, + locationResolver: testManagement.resolver.Location, + navigatorModel: { + spaces: [ + { + id: 'projects', + label: testManagement.string.Projects, + spaceClass: testManagement.class.TestProject, + addSpaceLabel: testManagement.string.CreateProject, + createComponent: testManagement.component.CreateProject, + icon: testManagement.icon.Home, + specials: [ + { + id: 'library', + label: testManagement.string.TestLibrary, + icon: testManagement.icon.TestLibrary, + component: workbench.component.SpecialView, + componentProps: { + _class: testManagement.class.TestCase, + icon: testManagement.icon.TestLibrary, + label: testManagement.string.TestLibrary, + createLabel: testManagement.string.CreateTestCase, + createComponent: testManagement.component.CreateTestCase + }, + navigationModel: { + navigationComponent: view.component.FoldersBrowser, + navigationComponentLabel: testManagement.string.TestSuites, + navigationComponentIcon: testManagement.icon.TestSuites, + mainComponentLabel: testManagement.string.TestCases, + mainComponentIcon: testManagement.icon.TestCases, + createComponent: testManagement.component.CreateTestSuite, + navigationComponentProps: { + _class: testManagement.class.TestSuite, + icon: testManagement.icon.TestSuites, + title: testManagement.string.TestSuites, + createLabel: testManagement.string.CreateTestSuite, + createComponent: testManagement.component.CreateTestSuite, + titleKey: 'name', + parentKey: 'parent', + noParentId: testManagement.ids.NoParent, + getFolderLink: testManagement.function.GetTestSuiteLink, + allObjectsLabel: testManagement.string.AllTestCases, + allObjectsIcon: testManagement.icon.TestSuites + }, + syncWithLocationQuery: true + } + } + /* TODO: UBERF-8584 + { + id: opt.testRunsId, + label: testManagement.string.TestRuns, + icon: testManagement.icon.TestRuns, + component: workbench.component.SpecialView, + componentProps: { + _class: testManagement.class.TestRun, + icon: testManagement.icon.TestRuns, + title: testManagement.string.TestRuns, + createLabel: testManagement.string.NewTestRun, + createComponent: testManagement.component.CreateTestRun + } + } */ + ] + } + ] + }, + navHeaderComponent: testManagement.component.NewTestCaseHeader + }, + testManagement.app.TestManagement + ) +} + +export function createModel (builder: Builder): void { + builder.createModel( + TTypeTestCaseType, + TTypeTestCasePriority, + TTypeTestCaseStatus, + TTestProject, + TTestSuite, + TTestCase, + TDefaultProjectTypeData, + TTestRun, + TTestRunItem, + TTypeTestRunResult + ) + + builder.mixin(testManagement.class.TestProject, core.class.Class, activity.mixin.ActivityDoc, {}) + + builder.createDoc(activity.class.ActivityExtension, core.space.Model, { + ofClass: testManagement.class.TestProject, + components: { input: chunter.component.ChatMessageInput } + }) + + defineTestSuite(builder) + defineTestCase(builder) + defineTestRun(builder) + + definePresenters(builder) + + defineApplication(builder) + + builder.mixin(testManagement.class.TestCase, core.class.Class, view.mixin.ObjectIcon, { + component: testManagement.component.TestCaseStatusPresenter + }) + + builder.createDoc(core.class.DomainIndexConfiguration, core.space.Model, { + domain: DOMAIN_TEST_MANAGEMENT, + disabled: [ + { space: 1 }, + { attachedToClass: 1 }, + { status: 1 }, + { project: 1 }, + { priority: 1 }, + { assignee: 1 }, + { sprint: 1 }, + { component: 1 }, + { category: 1 }, + { modifiedOn: 1 }, + { modifiedBy: 1 }, + { createdBy: 1 }, + { relations: 1 }, + { milestone: 1 }, + { createdOn: -1 } + ] + }) + + defineSpaceType(builder) +} + +function defineSpaceType (builder: Builder): void { + builder.createDoc( + core.class.SpaceTypeDescriptor, + core.space.Model, + { + name: testManagement.string.TestProject, + description: testManagement.string.FullDescription, + icon: testManagement.icon.TestProject, + baseClass: testManagement.class.TestProject, + availablePermissions: [ + core.permission.UpdateSpace, + core.permission.ArchiveSpace, + core.permission.ForbidDeleteObject + ] + }, + testManagement.descriptors.ProjectType + ) + + builder.createDoc( + core.class.SpaceType, + core.space.Model, + { + name: 'Default project type', + descriptor: testManagement.descriptors.ProjectType, + roles: 0, + targetClass: testManagement.mixin.DefaultProjectTypeData + }, + testManagement.spaceType.DefaultProject + ) +} + +function defineTestSuite (builder: Builder): void { + builder.mixin(testManagement.class.TestSuite, core.class.Class, activity.mixin.ActivityDoc, {}) + + builder.createDoc(activity.class.ActivityExtension, core.space.Model, { + ofClass: testManagement.class.TestSuite, + components: { input: chunter.component.ChatMessageInput } + }) + + builder.mixin(testManagement.class.TestSuite, core.class.Class, view.mixin.ObjectEditor, { + editor: testManagement.component.EditTestSuite + }) + + builder.mixin(testManagement.class.TestSuite, core.class.Class, view.mixin.ObjectPanel, { + component: testManagement.component.EditTestSuite + }) + + builder.mixin(testManagement.class.TestSuite, core.class.Class, view.mixin.ObjectPresenter, { + presenter: testManagement.component.TestSuitePresenter + }) + + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: testManagement.class.TestSuite, + descriptor: view.viewlet.Table, + config: ['', 'description'], + configOptions: { + strict: true + } + }, + testManagement.viewlet.TableTestSuites + ) + + // Actions + + builder.mixin(testManagement.class.TestSuite, core.class.Class, view.mixin.IgnoreActions, { + actions: [ + view.action.Open, + view.action.OpenInNewTab, + print.action.Print, + tracker.action.EditRelatedTargets, + tracker.action.NewRelatedIssue + ] + }) + + createAction( + builder, + { + action: testManagement.actionImpl.CreateChildTestSuite, + label: testManagement.string.CreateTestSuite, + icon: testManagement.icon.TestSuite, + category: testManagement.category.TestSuite, + input: 'none', + target: testManagement.class.TestSuite, + context: { + mode: ['context', 'browser'], + application: testManagement.app.TestManagement, + group: 'create' + } + }, + testManagement.action.CreateChildTestSuite + ) +} + +function defineTestCase (builder: Builder): void { + builder.mixin(testManagement.class.TestCase, core.class.Class, activity.mixin.ActivityDoc, {}) + + builder.createDoc(activity.class.ActivityExtension, core.space.Model, { + ofClass: testManagement.class.TestCase, + components: { input: chunter.component.ChatMessageInput } + }) + + builder.mixin(testManagement.class.TestCase, core.class.Class, view.mixin.ObjectEditor, { + editor: testManagement.component.EditTestCase + }) + + builder.mixin(testManagement.class.TestCase, core.class.Class, view.mixin.ObjectPanel, { + component: testManagement.component.EditTestCase + }) + + builder.mixin(testManagement.class.TestCase, core.class.Class, view.mixin.ObjectPresenter, { + presenter: testManagement.component.TestCasePresenter + }) + + builder.mixin(testManagement.class.TypeTestCaseStatus, core.class.Class, view.mixin.AttributeFilter, { + component: view.component.ValueFilter + }) + + builder.mixin(testManagement.class.TestSuite, core.class.Class, view.mixin.AttributePresenter, { + presenter: testManagement.component.TestSuiteRefPresenter + }) + + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: testManagement.class.TestCase, + descriptor: view.viewlet.Table, + config: ['', { key: 'attachedTo', label: testManagement.string.TestSuite }, 'status', 'assignee'], + configOptions: { + strict: true + } + }, + testManagement.viewlet.TableTestCase + ) + + const viewOptions: ViewOptionsModel = { + groupBy: ['attachedTo'], + orderBy: [ + ['status', SortingOrder.Ascending], + ['modifiedOn', SortingOrder.Descending], + ['createdOn', SortingOrder.Descending] + ], + other: [ + { + key: 'shouldShowAll', + type: 'toggle', + defaultValue: false, + actionTarget: 'category', + action: view.function.ShowEmptyGroups, + label: view.string.ShowEmptyGroups + } + ] + } + + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: testManagement.class.TestCase, + descriptor: view.viewlet.List, + configOptions: { + strict: true, + hiddenKeys: ['title'] + }, + config: [ + { key: '', displayProps: { fixed: 'left', key: 'lead' } }, + { + key: 'status', + props: { kind: 'list', size: 'small', shouldShowName: false } + }, + { key: 'modifiedOn', displayProps: { key: 'modified', fixed: 'right', dividerBefore: true } }, + { + key: 'assignee', + props: { kind: 'list', shouldShowName: false, avatarSize: 'x-small' }, + displayProps: { key: 'assignee', fixed: 'right' } + } + ], + viewOptions + }, + testManagement.viewlet.ListTestCase + ) + + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: testManagement.class.TestCase, + descriptor: view.viewlet.Table, + config: ['', 'assignee', 'modifiedOn'], + configOptions: { + sortable: true + }, + variant: 'short' + }, + testManagement.viewlet.SuiteTestCases + ) +} + +function defineTestRun (builder: Builder): void { + builder.mixin(testManagement.class.TestRun, core.class.Class, activity.mixin.ActivityDoc, {}) + + builder.createDoc(activity.class.ActivityExtension, core.space.Model, { + ofClass: testManagement.class.TestRun, + components: { input: chunter.component.ChatMessageInput } + }) + + builder.mixin(testManagement.class.TestRun, core.class.Class, view.mixin.ObjectEditor, { + editor: testManagement.component.EditTestRun + }) + + builder.mixin(testManagement.class.TestRun, core.class.Class, view.mixin.ObjectPanel, { + component: testManagement.component.EditTestRun + }) + + builder.mixin(testManagement.class.TestRun, core.class.Class, view.mixin.ObjectPresenter, { + presenter: testManagement.component.TestRunPresenter + }) + + builder.createDoc( + view.class.Viewlet, + core.space.Model, + { + attachTo: testManagement.class.TestRun, + descriptor: view.viewlet.Table, + config: [''], + configOptions: { + strict: true + } + }, + testManagement.viewlet.TableTestRun + ) +} + +export { testManagementOperation } from './migration' +export { default } from './plugin' diff --git a/models/test-management/src/migration.ts b/models/test-management/src/migration.ts new file mode 100644 index 0000000000..3169396e42 --- /dev/null +++ b/models/test-management/src/migration.ts @@ -0,0 +1,21 @@ +// +// Copyright © 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 MigrateOperation, type MigrationClient, type MigrationUpgradeClient } from '@hcengineering/model' + +export const testManagementOperation: MigrateOperation = { + async migrate (client: MigrationClient): Promise {}, + async upgrade (state: Map>, client: () => Promise): Promise {} +} diff --git a/models/test-management/src/plugin.ts b/models/test-management/src/plugin.ts new file mode 100644 index 0000000000..abf37a268f --- /dev/null +++ b/models/test-management/src/plugin.ts @@ -0,0 +1,49 @@ +// +// Copyright © 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 { testManagementId } from '@hcengineering/test-management' +import testManganement from '@hcengineering/test-management-resources/src/plugin' +import type { Doc, Ref } from '@hcengineering/core' +import { mergeIds } from '@hcengineering/platform' +import { type AnyComponent } from '@hcengineering/ui/src/types' +import type { Action, ActionCategory, ViewAction } from '@hcengineering/view' + +export default mergeIds(testManagementId, testManganement, { + action: { + DeleteTestCase: '' as Ref>, + CreateChildTestSuite: '' as Ref, + EditTestSuite: '' as Ref + }, + actionImpl: { + CreateChildTestSuite: '' as ViewAction, + EditTestSuite: '' as ViewAction + }, + category: { + TestSuite: '' as Ref + }, + component: { + CreateTestCase: '' as AnyComponent, + TestCasePresenter: '' as AnyComponent, + ProjectPresenter: '' as AnyComponent, + ProjectSpacePresenter: '' as AnyComponent, + TestSuitePresenter: '' as AnyComponent, + EditTestSuite: '' as AnyComponent, + EditTestCase: '' as AnyComponent, + CreateTestRun: '' as AnyComponent, + TestRunPresenter: '' as AnyComponent, + EditTestRun: '' as AnyComponent, + TestSuiteRefPresenter: '' as AnyComponent + } +}) diff --git a/models/test-management/src/presenters.ts b/models/test-management/src/presenters.ts new file mode 100644 index 0000000000..0b45b6df50 --- /dev/null +++ b/models/test-management/src/presenters.ts @@ -0,0 +1,56 @@ +// +// Copyright © 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 Builder } from '@hcengineering/model' +import core from '@hcengineering/model-core' +import view from '@hcengineering/model-view' +import testManagement from './plugin' + +/** + * Define presenters + */ +export function definePresenters (builder: Builder): void { + // + // Project + // + builder.mixin(testManagement.class.TestProject, core.class.Class, view.mixin.ObjectPresenter, { + presenter: testManagement.component.ProjectPresenter + }) + + builder.mixin(testManagement.class.TestProject, core.class.Class, view.mixin.SpacePresenter, { + presenter: testManagement.component.ProjectSpacePresenter + }) + + // + // Test Suite + // + builder.mixin(testManagement.class.TestSuite, core.class.Class, view.mixin.ObjectPresenter, { + presenter: testManagement.component.TestSuitePresenter + }) + + // + // Test Case + // + builder.mixin(testManagement.class.TestCase, core.class.Class, view.mixin.ObjectPresenter, { + presenter: testManagement.component.TestCasePresenter + }) + + // + // Type Test Case Status + // + builder.mixin(testManagement.class.TypeTestCaseStatus, core.class.Class, view.mixin.AttributePresenter, { + presenter: testManagement.component.TestCaseStatusPresenter + }) +} diff --git a/models/test-management/src/types.ts b/models/test-management/src/types.ts new file mode 100644 index 0000000000..1fca881944 --- /dev/null +++ b/models/test-management/src/types.ts @@ -0,0 +1,233 @@ +// +// Copyright © 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 { Employee } from '@hcengineering/contact' +import type { + TestCase, + TestSuite, + TestCaseType, + TestCasePriority, + TestCaseStatus, + TestProject, + TestRun, + TestRunResult, + TestRunItem +} from '@hcengineering/test-management' +import { type Attachment } from '@hcengineering/attachment' +import contact from '@hcengineering/contact' +import chunter from '@hcengineering/chunter' +import { getEmbeddedLabel } from '@hcengineering/platform' +import { + Account, + DateRangeMode, + IndexKind, + type RolesAssignment, + type Role, + Ref, + type Domain, + type Timestamp, + type Type, + type CollectionSize, + type CollaborativeDoc, + type Class +} from '@hcengineering/core' +import { + Mixin, + Model, + Prop, + TypeRef, + UX, + TypeMarkup, + Index, + TypeCollaborativeDoc, + TypeString, + Collection, + ReadOnly, + TypeDate, + Hidden +} from '@hcengineering/model' +import attachment from '@hcengineering/model-attachment' +import core, { TAttachedDoc, TDoc, TType, TTypedSpace } from '@hcengineering/model-core' + +import testManagement from './plugin' + +export { testManagementId } from '@hcengineering/test-management/src/index' + +export const DOMAIN_TEST_MANAGEMENT = 'test-management' as Domain + +/** @public */ +export function TypeTestCaseType (): Type { + return { _class: testManagement.class.TypeTestCaseType, label: testManagement.string.TestCaseType } +} + +@Model(testManagement.class.TypeTestCaseType, core.class.Type, DOMAIN_TEST_MANAGEMENT) +@UX(testManagement.string.TestCaseType) +export class TTypeTestCaseType extends TType {} + +/** @public */ +export function TypeTestCasePriority (): Type { + return { _class: testManagement.class.TypeTestCasePriority, label: testManagement.string.TestCasePriority } +} + +@Model(testManagement.class.TypeTestCasePriority, core.class.Type, DOMAIN_TEST_MANAGEMENT) +@UX(testManagement.string.TestCasePriority) +export class TTypeTestCasePriority extends TType {} + +/** @public */ +export function TypeTestCaseStatus (): Type { + return { _class: testManagement.class.TypeTestCaseStatus, label: testManagement.string.TestCaseStatus } +} + +@Model(testManagement.class.TypeTestCaseStatus, core.class.Type, DOMAIN_TEST_MANAGEMENT) +@UX(testManagement.string.TestCaseStatus) +export class TTypeTestCaseStatus extends TType {} + +@Model(testManagement.class.TestProject, core.class.TypedSpace) +@UX(testManagement.string.TestProject) +export class TTestProject extends TTypedSpace implements TestProject { + @Prop(TypeMarkup(), testManagement.string.FullDescription) + @Index(IndexKind.FullText) + fullDescription?: string +} + +@Mixin(testManagement.mixin.DefaultProjectTypeData, testManagement.class.TestProject) +@UX(getEmbeddedLabel('Default project'), testManagement.icon.TestProject) +export class TDefaultProjectTypeData extends TTestProject implements RolesAssignment { + [key: Ref]: Ref[] +} + +/** + * @public + */ +@Model(testManagement.class.TestSuite, core.class.Doc, DOMAIN_TEST_MANAGEMENT) +@UX(testManagement.string.TestSuite, testManagement.icon.TestSuite, testManagement.string.TestSuite) +export class TTestSuite extends TDoc implements TestSuite { + @Prop(TypeString(), testManagement.string.SuiteName) + @Index(IndexKind.FullText) + name!: string + + @Prop(TypeMarkup(), testManagement.string.SuiteDescription) + @Index(IndexKind.FullText) + description?: string + + @Prop(TypeRef(testManagement.class.TestSuite), testManagement.string.TestSuite) + parent!: Ref + + @Prop(Collection(testManagement.class.TestCase), testManagement.string.TestCases, { + shortLabel: testManagement.string.TestCase + }) + testCases?: CollectionSize + + declare space: Ref +} + +/** + * @public + */ +@Model(testManagement.class.TestCase, core.class.AttachedDoc, DOMAIN_TEST_MANAGEMENT) +@UX(testManagement.string.TestCase, testManagement.icon.TestCase, testManagement.string.TestCase) +export class TTestCase extends TAttachedDoc implements TestCase { + @Prop(TypeRef(testManagement.class.TestProject), core.string.Space) + @Index(IndexKind.Indexed) + @Hidden() + declare space: Ref + + @Prop(TypeRef(testManagement.class.TestSuite), core.string.AttachedTo) + @Index(IndexKind.Indexed) + declare attachedTo: Ref + + @Prop(TypeRef(testManagement.class.TestSuite), core.string.AttachedToClass) + @Index(IndexKind.Indexed) + @Hidden() + declare attachedToClass: Ref> + + @Prop(TypeString(), core.string.Collection) + @Hidden() + override collection: 'testCases' = 'testCases' + + @Prop(TypeString(), testManagement.string.TestName) + @Index(IndexKind.FullText) + name!: string + + @Prop(TypeCollaborativeDoc(), testManagement.string.FullDescription) + @Index(IndexKind.FullText) + description!: CollaborativeDoc + + @Prop(TypeTestCaseType(), testManagement.string.TestType) + @ReadOnly() + type!: TestCaseType + + @Prop(TypeTestCasePriority(), testManagement.string.TestPriority) + @ReadOnly() + priority!: TestCasePriority + + @Prop(TypeTestCaseStatus(), testManagement.string.TestStatus) + @ReadOnly() + status!: TestCaseStatus + + @Prop(TypeRef(contact.mixin.Employee), testManagement.string.TestAssignee) + assignee!: Ref + + @Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files }) + attachments?: CollectionSize + + @Prop(Collection(chunter.class.ChatMessage), chunter.string.Comments) + comments?: number +} + +@Model(testManagement.class.TestRun, core.class.Doc, DOMAIN_TEST_MANAGEMENT) +@UX(testManagement.string.TestRun) +export class TTestRun extends TDoc implements TestRun { + @Prop(TypeString(), testManagement.string.TestRunName) + @Index(IndexKind.FullText) + name!: string + + @Prop(TypeCollaborativeDoc(), testManagement.string.FullDescription) + @Index(IndexKind.FullText) + description!: CollaborativeDoc + + @Prop(TypeDate(DateRangeMode.DATETIME), testManagement.string.DueDate) + dueDate?: Timestamp + + @Prop(Collection(testManagement.class.TestRunItem), testManagement.string.TestRunItems, { + shortLabel: testManagement.string.TestRunItem + }) + items?: CollectionSize +} + +/** @public */ +export function TypeTestRunResult (): Type { + return { _class: testManagement.class.TypeTestRunResult, label: testManagement.string.TestRunResult } +} + +@Model(testManagement.class.TypeTestRunResult, core.class.Type, DOMAIN_TEST_MANAGEMENT) +@UX(testManagement.string.TestRunResult) +export class TTypeTestRunResult extends TType {} + +@Model(testManagement.class.TestRunItem, core.class.AttachedDoc, DOMAIN_TEST_MANAGEMENT) +@UX(testManagement.string.TestRunItem) +export class TTestRunItem extends TAttachedDoc implements TestRunItem { + @Prop(TypeRef(testManagement.class.TestRun), testManagement.string.TestRun) + testRun!: Ref + + @Prop(TypeRef(testManagement.class.TestCase), testManagement.string.TestCase) + testCase!: Ref + + @Prop(TypeTestRunResult(), testManagement.string.TestRunResult) + result?: TestRunResult + + @Prop(Collection(chunter.class.ChatMessage), chunter.string.Comments) + comments?: number +} diff --git a/models/test-management/tsconfig.json b/models/test-management/tsconfig.json new file mode 100644 index 0000000000..9765b6086d --- /dev/null +++ b/models/test-management/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/view/src/plugin.ts b/models/view/src/plugin.ts index 0fa27261a0..c1f25d7a67 100644 --- a/models/view/src/plugin.ts +++ b/models/view/src/plugin.ts @@ -88,7 +88,8 @@ export default mergeIds(viewId, view, { ImageViewer: '' as AnyComponent, VideoViewer: '' as AnyComponent, PDFViewer: '' as AnyComponent, - TextViewer: '' as AnyComponent + TextViewer: '' as AnyComponent, + FoldersBrowser: '' as AnyComponent }, string: { Table: '' as IntlString, diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..049b9510a8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "platform", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/packages/ui/src/components/SectionEmpty.svelte b/packages/ui/src/components/SectionEmpty.svelte new file mode 100644 index 0000000000..468b0c8b2f --- /dev/null +++ b/packages/ui/src/components/SectionEmpty.svelte @@ -0,0 +1,38 @@ + + + + +
+
+ +
+ + + +
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 135709bed7..53e08dd656 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -272,6 +272,7 @@ export { default as TimeZonesPopup } from './components/TimeZonesPopup.svelte' export { default as CodeForm } from './components/CodeForm.svelte' export { default as CodeInput } from './components/CodeInput.svelte' export { default as TimeLeft } from './components/TimeLeft.svelte' +export { default as SectionEmpty } from './components/SectionEmpty.svelte' export { default as Dock } from './components/Dock.svelte' diff --git a/plugins/test-management-assets/.eslintrc.js b/plugins/test-management-assets/.eslintrc.js new file mode 100644 index 0000000000..e73094bc7e --- /dev/null +++ b/plugins/test-management-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/test-management-assets/assets/icons.svg b/plugins/test-management-assets/assets/icons.svg new file mode 100644 index 0000000000..961c3705a9 --- /dev/null +++ b/plugins/test-management-assets/assets/icons.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/test-management-assets/config/rig.json b/plugins/test-management-assets/config/rig.json new file mode 100644 index 0000000000..b75800b9b7 --- /dev/null +++ b/plugins/test-management-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/test-management-assets/jest.config.js b/plugins/test-management-assets/jest.config.js new file mode 100644 index 0000000000..2cfd408b67 --- /dev/null +++ b/plugins/test-management-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/test-management-assets/lang/en.json b/plugins/test-management-assets/lang/en.json new file mode 100644 index 0000000000..135650b31c --- /dev/null +++ b/plugins/test-management-assets/lang/en.json @@ -0,0 +1,66 @@ +{ + "string": { + "ConfigLabel": "Test Management", + "ConfigDescription": "Extension to manage test cases", + "TestCaseType": "Type", + "TestCasePriority": "Priority", + "TestCaseStatus": "Status", + "TestSuite": "Test Suite", + "SuiteName": "Name", + "SuiteDescription": "Description", + "Suite": "Suite", + "TestName": "Name", + "TestDescription": "Description", + "TestType": "Type", + "TestPriority": "Priority", + "TestStatus": "Status", + "TestEstimatedTime": "Estimated time", + "TestPreconditions": "Preconditions", + "TestSteps": "Steps", + "TestAssignee": "Assignee", + "TestCase": "Test case", + "TestProject": "Project", + "TestManagementApplication": "Test Management", + "AllTestCases": "All test cases", + "AllProjects": "All projects", + "Projects": "Projects", + "CreateProject": "Create project", + "EditProject": "Edit project", + "TestCases": "Test cases", + "TestManagementDescription": "Extension to manage test cases", + "CreateTestCase": "New test case", + "FullDescription": "Description", + "ProjectName": "Name", + "ProjectType": "Type", + "Members": "Members", + "RoleLabel": "Role", + "ProjectMembers": "Project members", + "TestSuites": "Test suites", + "CreateTestSuite": "Create test suite", + "NamePlaceholder": "Suite name", + "DescriptionPlaceholder": "Description (optional)", + "TestRuns": "Test runs", + "NewTestRun": "New test run", + "TestRun": "Test run", + "TestNamePlaceholder": "Test case title", + "ChooseIcon": "Choose icon", + "NoTestSuite": "No test suite", + "StatusDraft": "Draft", + "StatusReview": "Ready for review", + "StatusReviewComments": "Need to fix review comments", + "StatusApproved": "Approved", + "StatusRejected": "Rejected", + "SetStatus": "Set status", + "Assignee": "Assignee", + "Unassigned": "Unassigned", + "AssignTo": "Assign to", + "AssignedTo": "Assigneed to", + "PreviousAssigned": "Previously assigned", + "NoTestCases": "There are no test cases in this test suite", + "CreateTestRun": "Create test run", + "TestRunNamePlaceholder": "Test run name", + "SelectTestSuites": "Select test suites", + "SelectTestCases": "Select test cases", + "TestLibrary": "Test library" + } +} diff --git a/plugins/test-management-assets/lang/fr.json b/plugins/test-management-assets/lang/fr.json new file mode 100644 index 0000000000..c2f3353047 --- /dev/null +++ b/plugins/test-management-assets/lang/fr.json @@ -0,0 +1,66 @@ +{ + "string": { + "ConfigLabel": "Gestion des tests", + "ConfigDescription": "Extension pour gérer les cas de tests", + "TestCaseType": "Taper", + "TestCasePriority": "Priorité", + "TestCaseStatus": "Statut", + "TestSuite": "Suite de tests", + "SuiteName": "Nom", + "SuiteDescription": "Description", + "Suite": "Suite", + "TestName": "Nom", + "TestDescription": "Description", + "TestType": "Taper", + "TestPriority": "Priorité", + "TestStatus": "Statut", + "TestEstimatedTime": "Temps estimé", + "TestPreconditions": "Conditions préalables", + "TestSteps": "Mesures", + "TestAssignee": "Cessionnaire", + "TestCase": "Cas de test", + "TestProject": "Projet", + "TestManagementApplication": "Gestion des tests", + "AllTestCases": "Tous les cas de tests", + "AllProjects": "Tous les projets", + "Projects": "Projets", + "CreateProject": "Créer un projet", + "EditProject": "Modifier le projet", + "TestCases": "Cas de tests", + "TestManagementDescription": "Extension pour gérer les cas de tests", + "CreateTestCase": "Nouveau cas de test", + "FullDescription": "Description", + "ProjectName": "Nom", + "ProjectType": "Taper", + "Members": "Membres", + "RoleLabel": "Rôle", + "ProjectMembers": "Membres du projet", + "TestSuites": "Suites de tests", + "CreateTestSuite": "Créer une suite de tests", + "NamePlaceholder": "Nom de la suite", + "DescriptionPlaceholder": "Description (facultatif)", + "TestRuns": "Exécutions de tests", + "NewTestRun": "Nouveau test", + "TestRun": "Exécution d'essai", + "TestNamePlaceholder": "Titre du scénario de test", + "ChooseIcon": "Choisir l'icône", + "NoTestSuite": "Pas de suite de tests", + "StatusDraft": "Brouillon", + "StatusReview": "Prêt pour l'examen", + "StatusReviewComments": "Besoin de corriger les commentaires d'évaluation", + "StatusApproved": "Approuvé", + "StatusRejected": "Rejeté", + "SetStatus": "Définir le statut", + "Assignee": "Attribué à", + "Unassigned": "Non assigné", + "AssignTo": "Assigner à...", + "AssignedTo": "Assigné à {value}", + "PreviousAssigned": "Assigné précédemment", + "NoTestCases": "Il n'y a aucun cas de test dans cette suite de tests", + "CreateTestRun": "Créer une série de tests", + "TestRunNamePlaceholder": "Nom de l'exécution du test", + "SelectTestSuites": "Sélectionnez les suites de tests", + "SelectTestCases": "Sélectionnez des cas de test", + "TestLibrary": "Bibliothèque de tests" + } +} diff --git a/plugins/test-management-assets/lang/ru.json b/plugins/test-management-assets/lang/ru.json new file mode 100644 index 0000000000..19a45e0d6c --- /dev/null +++ b/plugins/test-management-assets/lang/ru.json @@ -0,0 +1,66 @@ +{ + "string": { + "ConfigLabel": "Управление тестированием", + "ConfigDescription": "Расширение для управления тестирование", + "TestCaseType": "Тип", + "TestCasePriority": "Приоритет", + "TestCaseStatus": "Статус", + "TestSuite": "Тестовый набор", + "SuiteName": "Имя", + "SuiteDescription": "Описание", + "Suite": "Тестовый набор", + "TestName": "Имя", + "TestDescription": "Описание", + "TestType": "Тип", + "TestPriority": "Приоритет", + "TestStatus": "Статус", + "TestEstimatedTime": "Расчетное время", + "TestPreconditions": "Предварительные условия", + "TestSteps": "Шаги", + "TestAssignee": "Исполнитель", + "TestCase": "Тест-кейс", + "TestProject": "Проект", + "TestManagementApplication": "Управление тестированием", + "AllTestCases": "Все тест-кейсы", + "AllProjects": "Все проекты", + "Projects": "Проекты", + "CreateProject": "Создать проект", + "EditProject": "Отредактировать проект", + "TestCases": "Тест-кейсы", + "TestManagementDescription": "Расширение для управления тестирование", + "CreateTestCase": "Новый тест-кейс", + "FullDescription": "Описание", + "ProjectName": "Имя", + "ProjectType": "Тип", + "Members": "Участники", + "RoleLabel": "Роль", + "ProjectMembers": "Участники проекта", + "TestSuites": "Тестовые наборы", + "CreateTestSuite": "Создать тестовый набор", + "NamePlaceholder": "Имя тестового набора", + "DescriptionPlaceholder": "Описание (опционально)", + "TestRuns": "Выполнение тестов", + "NewTestRun": "Новый тест план", + "TestRun": "Тест план", + "TestNamePlaceholder": "Имя тест кейса", + "ChooseIcon": "Выберите иконку", + "NoTestSuite": "Тестовый набор не задан", + "StatusDraft": "В прогрессе", + "StatusReview": "Готов для ревью", + "StatusReviewComments": "Требует исправлений", + "StatusApproved": "Согласован", + "StatusRejected": "Отклонен", + "SetStatus": "Выбрать статус", + "Assignee": "Исполнитель", + "Unassigned": "Не назначен", + "AssignTo": "Назначить на", + "AssignedTo": "Назначено на", + "PreviousAssigned": "Ранее назначенные", + "NoTestCases": "Тест-кейсы отсутствует", + "CreateTestRun": "Создать тест план", + "TestRunNamePlaceholder": "Название тест плана", + "SelectTestSuites": "Выбрать наборы тестов", + "SelectTestCases": "Выбрать тест-кейсы", + "TestLibrary": "Библиотека тестов" + } +} diff --git a/plugins/test-management-assets/lang/zh.json b/plugins/test-management-assets/lang/zh.json new file mode 100644 index 0000000000..c7da64156d --- /dev/null +++ b/plugins/test-management-assets/lang/zh.json @@ -0,0 +1,66 @@ +{ + "string": { + "ConfigLabel": "測試管理", + "ConfigDescription": "管理測試用例的擴展", + "TestCaseType": "類型", + "TestCasePriority": "優先事項", + "TestCaseStatus": "地位", + "TestSuite": "測試套件", + "SuiteName": "姓名", + "SuiteDescription": "描述", + "Suite": "Suite", + "TestName": "姓名", + "TestDescription": "描述", + "TestType": "類型", + "TestPriority": "優先事項", + "TestStatus": "地位", + "TestEstimatedTime": "預計時間", + "TestPreconditions": "前提條件", + "TestSteps": "步驟", + "TestAssignee": "受讓人", + "TestCase": "測試用例", + "TestProject": "專案", + "TestManagementApplication": "測試管理", + "AllTestCases": "所有測試用例", + "AllProjects": "所有項目", + "Projects": "專案", + "CreateProject": "創建專案", + "EditProject": "編輯項目", + "TestCases": "測試用例", + "TestManagementDescription": "管理測試用例的擴展", + "CreateTestCase": "新測試用例", + "FullDescription": "描述", + "ProjectName": "姓名", + "ProjectType": "類型", + "Members": "會員", + "RoleLabel": "角色", + "ProjectMembers": "專案成員", + "TestSuites": "測試套件", + "CreateTestSuite": "建立測試套件", + "NamePlaceholder": "套房名稱", + "DescriptionPlaceholder": "說明(可選)", + "TestRuns": "試運行", + "NewTestRun": "新試運行", + "TestRun": "試運行", + "TestNamePlaceholder": "測試用例標題", + "ChooseIcon": "選擇圖示", + "NoTestSuite": "沒有測試套件", + "StatusDraft": "草稿", + "StatusReview": "準備審查", + "StatusReviewComments": "需要修復審核意見", + "StatusApproved": "得到正式認可的", + "StatusRejected": "被拒絕", + "SetStatus": "設定狀態", + "Assignee": "受讓人", + "Unassigned": "未分配", + "AssignTo": "分配給", + "AssignedTo": "分配給", + "PreviousAssigned": "先前分配的", + "NoTestCases": "該測試套件中沒有測試案例", + "CreateTestRun": "建立測試運行", + "TestRunNamePlaceholder": "測試運行名稱", + "SelectTestSuites": "選擇測試套件", + "SelectTestCases": "選擇測試用例", + "TestLibrary": "測試庫" + } +} diff --git a/plugins/test-management-assets/package.json b/plugins/test-management-assets/package.json new file mode 100644 index 0000000000..f4e58bf2ee --- /dev/null +++ b/plugins/test-management-assets/package.json @@ -0,0 +1,39 @@ +{ + "name": "@hcengineering/test-management-assets", + "version": "0.6.0", + "main": "src/index.ts", + "author": "Anticrm Platform Contributors", + "template": "@hcengineering/assets-package", + "license": "EPL-2.0", + "scripts": { + "build": "compile", + "test": "jest --passWithNoTests --silent", + "build:docs": "", + "format": "format src", + "build:watch": "compile", + "_phase:build": "compile transpile src", + "_phase:test": "jest --passWithNoTests --silent", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "@hcengineering/platform-rig": "^0.6.0", + "@typescript-eslint/eslint-plugin": "^6.11.0", + "@typescript-eslint/parser": "^6.11.0", + "eslint-config-standard-with-typescript": "^40.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.4.0", + "eslint-plugin-promise": "^6.1.1", + "eslint": "^8.54.0", + "prettier": "^3.1.0", + "@types/node": "~20.11.16", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "typescript": "^5.3.3" + }, + "dependencies": { + "@hcengineering/platform": "^0.6.11", + "@hcengineering/test-management": "^0.6.0" + } +} diff --git a/plugins/test-management-assets/src/__tests__/lang.test.ts b/plugins/test-management-assets/src/__tests__/lang.test.ts new file mode 100644 index 0000000000..cf96c6dcf7 --- /dev/null +++ b/plugins/test-management-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/test-management-assets/src/index.ts b/plugins/test-management-assets/src/index.ts new file mode 100644 index 0000000000..5498b02acc --- /dev/null +++ b/plugins/test-management-assets/src/index.ts @@ -0,0 +1,40 @@ +// +// Copyright © 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 testManagement from '@hcengineering/test-management' +import { loadMetadata } from '@hcengineering/platform' + +const icons = require('../assets/icons.svg') as string // eslint-disable-line +loadMetadata(testManagement.icon, { + TestCase: `${icons}#testCase`, + TestManagementApplication: `${icons}#testManagementApplication`, + TestManagement: `${icons}#testCase`, + TestManagementVersion: `${icons}#testCase`, + TestCases: `${icons}#testCase`, + Home: `${icons}#home`, + Estimation: `${icons}#testCase`, + TestSuite: `${icons}#testSuite`, + TestProject: `${icons}#testCase`, + TestSuites: `${icons}#testSuite`, + TestRuns: `${icons}#testRun`, + RedCircle: `${icons}#red-circle`, + Document: `${icons}#document`, + StatusDraft: `${icons}#status-draft`, + StatusReview: `${icons}#status-review`, + StatusReviewComments: `${icons}#status-review-comments`, + StatusApproved: `${icons}#status-approved`, + StatusRejected: `${icons}#status-canceled`, + TestLibrary: `${icons}#test-library` +}) diff --git a/plugins/test-management-assets/tsconfig.json b/plugins/test-management-assets/tsconfig.json new file mode 100644 index 0000000000..4449c73536 --- /dev/null +++ b/plugins/test-management-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/test-management-resources/.eslintrc.js b/plugins/test-management-resources/.eslintrc.js new file mode 100644 index 0000000000..bb8fd7450d --- /dev/null +++ b/plugins/test-management-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/test-management-resources/.prettierrc b/plugins/test-management-resources/.prettierrc new file mode 100644 index 0000000000..792942803a --- /dev/null +++ b/plugins/test-management-resources/.prettierrc @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "trailingComma": "none", + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "printWidth": 120, + "useTabs": false, + "bracketSpacing": true, + "proseWrap": "preserve", + "plugins": [ + "prettier-plugin-svelte" + ], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + } + ] +} \ No newline at end of file diff --git a/plugins/test-management-resources/config/rig.json b/plugins/test-management-resources/config/rig.json new file mode 100644 index 0000000000..bcad6f7c33 --- /dev/null +++ b/plugins/test-management-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/test-management-resources/jest.config.js b/plugins/test-management-resources/jest.config.js new file mode 100644 index 0000000000..3656e284d3 --- /dev/null +++ b/plugins/test-management-resources/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'] +} diff --git a/plugins/test-management-resources/package.json b/plugins/test-management-resources/package.json new file mode 100644 index 0000000000..7cec2be751 --- /dev/null +++ b/plugins/test-management-resources/package.json @@ -0,0 +1,77 @@ +{ + "name": "@hcengineering/test-management-resources", + "version": "0.6.0", + "main": "src/index.ts", + "author": "Anticrm Platform Contributors", + "license": "EPL-2.0", + "scripts": { + "build": "compile ui", + "build:docs": "api-extractor run --local", + "svelte-check": "do-svelte-check", + "_phase:svelte-check": "do-svelte-check", + "format": "format src", + "build:watch": "compile ui", + "_phase:build": "compile ui", + "_phase:format": "format src", + "_phase:validate": "compile validate" + }, + "devDependencies": { + "svelte-loader": "^3.2.0", + "sass": "^1.53.0", + "svelte-preprocess": "^5.1.3", + "@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-plugin-svelte": "^2.35.1", + "prettier-plugin-svelte": "^3.2.2", + "eslint": "^8.54.0", + "prettier": "^3.1.0", + "svelte-check": "^3.6.9", + "typescript": "^5.3.3", + "jest": "^29.7.0", + "ts-jest": "^29.1.1", + "@types/jest": "^29.5.5", + "svelte-eslint-parser": "^0.33.1" + }, + "dependencies": { + "@hcengineering/activity": "^0.6.0", + "@hcengineering/activity-resources": "^0.6.1", + "@hcengineering/analytics": "^0.6.0", + "@hcengineering/attachment": "^0.6.14", + "@hcengineering/attachment-resources": "^0.6.0", + "@hcengineering/calendar": "^0.6.24", + "@hcengineering/chunter": "^0.6.20", + "@hcengineering/chunter-resources": "^0.6.0", + "@hcengineering/client": "^0.6.18", + "@hcengineering/contact": "^0.6.24", + "@hcengineering/contact-resources": "^0.6.0", + "@hcengineering/core": "^0.6.32", + "@hcengineering/kanban": "^0.6.0", + "@hcengineering/login": "^0.6.12", + "@hcengineering/notification": "^0.6.23", + "@hcengineering/notification-resources": "^0.6.0", + "@hcengineering/panel": "^0.6.23", + "@hcengineering/platform": "^0.6.11", + "@hcengineering/preference": "^0.6.13", + "@hcengineering/presentation": "^0.6.3", + "@hcengineering/query": "^0.6.12", + "@hcengineering/setting": "^0.6.17", + "@hcengineering/tags": "^0.6.16", + "@hcengineering/task": "^0.6.20", + "@hcengineering/task-resources": "^0.6.0", + "@hcengineering/text-editor-resources": "^0.6.0", + "@hcengineering/text": "^0.6.5", + "@hcengineering/test-management": "^0.6.0", + "@hcengineering/ui": "^0.6.15", + "@hcengineering/view": "^0.6.13", + "@hcengineering/view-resources": "^0.6.0", + "@hcengineering/workbench": "^0.6.16", + "@hcengineering/workbench-resources": "^0.6.1", + "fast-equals": "^5.0.1", + "svelte": "^4.2.19" + } +} diff --git a/plugins/test-management-resources/postcss.config.js b/plugins/test-management-resources/postcss.config.js new file mode 100644 index 0000000000..88752c6cb0 --- /dev/null +++ b/plugins/test-management-resources/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: [ + require('autoprefixer') + ] +} diff --git a/plugins/test-management-resources/src/components/icons/FileDuo.svelte b/plugins/test-management-resources/src/components/icons/FileDuo.svelte new file mode 100644 index 0000000000..71f6f606b2 --- /dev/null +++ b/plugins/test-management-resources/src/components/icons/FileDuo.svelte @@ -0,0 +1,32 @@ + + + + + + + + + + + diff --git a/plugins/test-management-resources/src/components/project/CreateProject.svelte b/plugins/test-management-resources/src/components/project/CreateProject.svelte new file mode 100644 index 0000000000..488f393ab0 --- /dev/null +++ b/plugins/test-management-resources/src/components/project/CreateProject.svelte @@ -0,0 +1,390 @@ + + + + +
+
+
+
+ + +
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + {#each roles as role} +
+
+
+ { + handleRoleAssignmentChanged(role._id, refs) + }} + kind={'regular'} + size={'large'} + /> +
+ {/each} +
+
diff --git a/plugins/test-management-resources/src/components/project/ProjectPresenter.svelte b/plugins/test-management-resources/src/components/project/ProjectPresenter.svelte new file mode 100644 index 0000000000..e683b907f2 --- /dev/null +++ b/plugins/test-management-resources/src/components/project/ProjectPresenter.svelte @@ -0,0 +1,29 @@ + + + +{#if value} +
+ + {value.name} + +
+{/if} diff --git a/plugins/test-management-resources/src/components/project/ProjectSpacePresenter.svelte b/plugins/test-management-resources/src/components/project/ProjectSpacePresenter.svelte new file mode 100644 index 0000000000..40dba55896 --- /dev/null +++ b/plugins/test-management-resources/src/components/project/ProjectSpacePresenter.svelte @@ -0,0 +1,105 @@ + + + +{#if specials} + getActions(space)} + {forciblyСollapsed} + > + {#each specials as special} + + + + {/each} + + + {#if visible} + {@const item = specials.find((sp) => sp.id === currentSpecial && currentSpace === space._id)} + {#if item} + + + + {/if} + {/if} + + +{/if} diff --git a/plugins/test-management-resources/src/components/test-case/AssigneeEditor.svelte b/plugins/test-management-resources/src/components/test-case/AssigneeEditor.svelte new file mode 100644 index 0000000000..ea405cd046 --- /dev/null +++ b/plugins/test-management-resources/src/components/test-case/AssigneeEditor.svelte @@ -0,0 +1,198 @@ + + + +{#if _object} + {#if isAction} + { + const result = evt.detail + if (result === null) { + handleAssigneeChanged(null) + } else if (result !== undefined && result._id !== value) { + value = result._id + handleAssigneeChanged(result._id) + } + }} + /> + {:else} + handleAssigneeChanged(detail)} + /> + {/if} +{/if} diff --git a/plugins/test-management-resources/src/components/test-case/CreateTestCase.svelte b/plugins/test-management-resources/src/components/test-case/CreateTestCase.svelte new file mode 100644 index 0000000000..aee61920a7 --- /dev/null +++ b/plugins/test-management-resources/src/components/test-case/CreateTestCase.svelte @@ -0,0 +1,200 @@ + + + + + + 0} + on:close={() => { + dispatch('close') + }} + on:changeContent +> + + + + + +
+ +
+ + { + if (ev.detail.size > 0) attachments = ev.detail.values + else if (ev.detail.size === 0 && ev.detail.values != null) { + attachments.clear() + attachments = attachments + } + }} + /> + + + (object.assignee = detail)} + /> + + + + + {#if attachments.size > 0} + {#each Array.from(attachments.values()) as attachment} + { + if (result.detail !== undefined) descriptionBox.removeAttachmentById(result.detail._id) + }} + /> + {/each} + {/if} + + + + +{:else if kind === 'list-header'} +
+ {#if shouldShowAvatar} + + {/if} + +
+{:else} +