From f55cc3adc63f592d8e2a2186f253b882f06b9d8f Mon Sep 17 00:00:00 2001 From: Artyom Savchenko Date: Tue, 19 May 2026 23:09:24 +0700 Subject: [PATCH] Add action to add new product version (#10865) Signed-off-by: Artem Savchenko --- models/products/src/index.ts | 15 ++++++++++++ models/products/src/plugin.ts | 7 +++++- plugins/products-resources/src/index.ts | 12 +++++++++- plugins/products-resources/src/utils.ts | 32 +++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/models/products/src/index.ts b/models/products/src/index.ts index 8951fb52c9..bfd8efe585 100644 --- a/models/products/src/index.ts +++ b/models/products/src/index.ts @@ -254,6 +254,21 @@ function defineProduct (builder: Builder): void { builder.mixin(products.class.Product, core.class.Class, view.mixin.IgnoreActions, { actions: [tracker.action.NewRelatedIssue] }) + + createAction( + builder, + { + action: products.actionImpl.CreateProductVersion, + label: products.string.CreateProductVersion, + icon: products.icon.ProductVersion, + visibilityTester: products.function.CanCreateProductVersion, + category: view.category.General, + input: 'focus', + target: products.class.Product, + context: { mode: ['context', 'browser'], group: 'create' } + }, + products.action.CreateProductVersion + ) } function defineSpaceType (builder: Builder): void { diff --git a/models/products/src/plugin.ts b/models/products/src/plugin.ts index 64d0929906..aa0463d6af 100644 --- a/models/products/src/plugin.ts +++ b/models/products/src/plugin.ts @@ -19,12 +19,16 @@ import products from '@hcengineering/products-resources/src/plugin' import type { Client, Doc, Ref, Role } from '@hcengineering/core' import { type Resource, mergeIds } from '@hcengineering/platform' import { type AnyComponent } from '@hcengineering/ui/src/types' -import type { Action } from '@hcengineering/view' +import type { Action, ViewAction } from '@hcengineering/view' export default mergeIds(productsId, products, { action: { + CreateProductVersion: '' as Ref>, DeleteProductVersion: '' as Ref> }, + actionImpl: { + CreateProductVersion: '' as ViewAction + }, ids: { ModulePermissionGroup: '' as Ref, ModulePermissionGroupReadOnlyGuest: '' as Ref @@ -44,6 +48,7 @@ export default mergeIds(productsId, products, { ProductVersionVersionPresenter: '' as AnyComponent }, function: { + CanCreateProductVersion: '' as Resource<(doc?: Doc | Doc[]) => Promise>, CanDeleteProductVersion: '' as Resource<(doc?: Doc | Doc[]) => Promise>, ProductIdentifierProvider: '' as Resource<(client: Client, ref: Ref, doc?: T) => Promise> }, diff --git a/plugins/products-resources/src/index.ts b/plugins/products-resources/src/index.ts index bad1378879..f126b95e4c 100644 --- a/plugins/products-resources/src/index.ts +++ b/plugins/products-resources/src/index.ts @@ -34,7 +34,13 @@ import ProductVersionsPresenter from './components/product-version/ProductVersio import ProductVersionStateEditor from './components/product-version/ProductVersionStateEditor.svelte' import ProductVersionStatePresenter from './components/product-version/ProductVersionStatePresenter.svelte' import ProductVersionVersionPresenter from './components/product-version/ProductVersionVersionPresenter.svelte' -import { canDeleteProductVersion, getVisibleFilters, productIdentifierProvider } from './utils' +import { + canCreateProductVersion, + canDeleteProductVersion, + createProductVersion, + getVisibleFilters, + productIdentifierProvider +} from './utils' const toObjectSearchResult = (e: WithLookup): ObjectSearchResult => ({ doc: e, @@ -86,7 +92,11 @@ export default async (): Promise => ({ }, function: { GetVisibleFilters: getVisibleFilters, + CanCreateProductVersion: canCreateProductVersion, CanDeleteProductVersion: canDeleteProductVersion, ProductIdentifierProvider: productIdentifierProvider + }, + actionImpl: { + CreateProductVersion: createProductVersion } }) diff --git a/plugins/products-resources/src/utils.ts b/plugins/products-resources/src/utils.ts index bcbf1532a7..a710682c76 100644 --- a/plugins/products-resources/src/utils.ts +++ b/plugins/products-resources/src/utils.ts @@ -21,10 +21,13 @@ import core, { getCurrentAccount } from '@hcengineering/core' import { getClient } from '@hcengineering/presentation' +import { showPopup } from '@hcengineering/ui' import { type KeyFilter } from '@hcengineering/view' import documents from '@hcengineering/controlled-documents' import products, { ProductVersionState, type Product, type ProductVersion } from '@hcengineering/products' +import CreateProductVersion from './components/product-version/CreateProductVersion.svelte' + export function getProductVersionVersion (doc: ProductVersion): string { const codename = doc.codename ?? '' const version = `${doc.major}.${doc.minor}.${doc.patch}` @@ -79,6 +82,35 @@ export async function canEditProductVersion (doc?: WithLookup): return await canEditProduct(product) } +export async function canCreateProductVersion (doc?: Product | Product[]): Promise { + if (doc === null || doc === undefined) { + return false + } + + if (Array.isArray(doc)) { + return false + } + + if (doc.archived) { + return false + } + + return await canEditProduct(doc) +} + +export async function createProductVersion (doc?: Product | Product[]): Promise { + if (doc === null || doc === undefined) { + return + } + + const product = Array.isArray(doc) ? doc[0] : doc + if (product === undefined) { + return + } + + showPopup(CreateProductVersion, { space: product._id }, 'top') +} + export async function canDeleteProductVersion (doc?: ProductVersion | ProductVersion[]): Promise { if (doc === null || doc === undefined) { return false