From 40bf81338c4441b542948ef772e2508b207a6b85 Mon Sep 17 00:00:00 2001 From: Jan Cizmar Date: Mon, 24 Feb 2025 16:01:53 +0100 Subject: [PATCH 01/16] feat: Add keys as metric > prepared entities & other parts of backend --- ee/backend/app/src/main/kotlin/io/tolgee/ee/data/UsageData.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/ee/backend/app/src/main/kotlin/io/tolgee/ee/data/UsageData.kt b/ee/backend/app/src/main/kotlin/io/tolgee/ee/data/UsageData.kt index d3a95e459b..ddbf97a92b 100644 --- a/ee/backend/app/src/main/kotlin/io/tolgee/ee/data/UsageData.kt +++ b/ee/backend/app/src/main/kotlin/io/tolgee/ee/data/UsageData.kt @@ -5,6 +5,7 @@ import java.math.BigDecimal data class UsageData( val seatsUsage: List, val translationsUsage: List, + val keysUsage: List, val creditsUsage: SumUsageItem?, val subscriptionPrice: BigDecimal?, val appliedStripeCredits: BigDecimal?, From 83a23d3ebd6943fbbfd1546fc76ba8cc0caea90f Mon Sep 17 00:00:00 2001 From: Jan Cizmar Date: Tue, 25 Feb 2025 16:05:15 +0100 Subject: [PATCH 02/16] chore: KtLint --- .../hateoas/ee/PlanIncludedUsageModel.kt | 1 + .../io/tolgee/hateoas/ee/PlanPricesModel.kt | 3 +++ .../io/tolgee/fixtures/dateFromString.kt | 15 +++++++++++++ .../kotlin/io/tolgee/AbstractSpringTest.kt | 22 +++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 backend/misc/src/main/kotlin/io/tolgee/fixtures/dateFromString.kt diff --git a/backend/api/src/main/kotlin/io/tolgee/hateoas/ee/PlanIncludedUsageModel.kt b/backend/api/src/main/kotlin/io/tolgee/hateoas/ee/PlanIncludedUsageModel.kt index 644595c7f8..b05829cce8 100644 --- a/backend/api/src/main/kotlin/io/tolgee/hateoas/ee/PlanIncludedUsageModel.kt +++ b/backend/api/src/main/kotlin/io/tolgee/hateoas/ee/PlanIncludedUsageModel.kt @@ -11,4 +11,5 @@ open class PlanIncludedUsageModel( var translationSlots: Long = -1L, var translations: Long = -1L, var mtCredits: Long = -1L, + var keys: Long = -1L, ) : RepresentationModel(), Serializable diff --git a/backend/api/src/main/kotlin/io/tolgee/hateoas/ee/PlanPricesModel.kt b/backend/api/src/main/kotlin/io/tolgee/hateoas/ee/PlanPricesModel.kt index fb3feabafd..3be6275c19 100644 --- a/backend/api/src/main/kotlin/io/tolgee/hateoas/ee/PlanPricesModel.kt +++ b/backend/api/src/main/kotlin/io/tolgee/hateoas/ee/PlanPricesModel.kt @@ -13,4 +13,7 @@ open class PlanPricesModel( val perThousandMtCredits: BigDecimal? = BigDecimal.ZERO, val subscriptionMonthly: BigDecimal = BigDecimal.ZERO, val subscriptionYearly: BigDecimal = BigDecimal.ZERO, + val perThousandKeys: BigDecimal = BigDecimal.ZERO, ) : RepresentationModel(), Serializable + +// TODO: Test it always counts usage, to handle situation when user switches between free plan, strings or key based plans. diff --git a/backend/misc/src/main/kotlin/io/tolgee/fixtures/dateFromString.kt b/backend/misc/src/main/kotlin/io/tolgee/fixtures/dateFromString.kt new file mode 100644 index 0000000000..9bba2b10ef --- /dev/null +++ b/backend/misc/src/main/kotlin/io/tolgee/fixtures/dateFromString.kt @@ -0,0 +1,15 @@ +package io.tolgee.fixtures + +import java.time.LocalDate +import java.time.ZoneId +import java.time.format.DateTimeFormatter +import java.util.* + +fun dateFromString( + dateString: String, + pattern: String = "yyyy-MM-dd", +): Date { + val formatter = DateTimeFormatter.ofPattern(pattern) + val localDate = LocalDate.parse(dateString, formatter) + return Date.from(localDate.atStartOfDay(ZoneId.of("UTC")).toInstant()) +} diff --git a/backend/testing/src/main/kotlin/io/tolgee/AbstractSpringTest.kt b/backend/testing/src/main/kotlin/io/tolgee/AbstractSpringTest.kt index 9b6167ec6e..7029b96979 100644 --- a/backend/testing/src/main/kotlin/io/tolgee/AbstractSpringTest.kt +++ b/backend/testing/src/main/kotlin/io/tolgee/AbstractSpringTest.kt @@ -1,6 +1,7 @@ package io.tolgee import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue import io.tolgee.activity.ActivityService import io.tolgee.component.AllCachesProvider import io.tolgee.component.CurrentDateProvider @@ -19,6 +20,8 @@ import io.tolgee.configuration.tolgee.machineTranslation.TolgeeMachineTranslatio import io.tolgee.constants.MtServiceType import io.tolgee.development.DbPopulatorReal import io.tolgee.development.testDataBuilder.TestDataService +import io.tolgee.fixtures.andGetContentAsString +import io.tolgee.fixtures.andIsOk import io.tolgee.repository.EmailVerificationRepository import io.tolgee.repository.KeyRepository import io.tolgee.repository.OrganizationRepository @@ -56,6 +59,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.cache.CacheManager import org.springframework.context.ApplicationContext +import org.springframework.test.web.servlet.ResultActions import org.springframework.transaction.PlatformTransactionManager import org.springframework.transaction.TransactionDefinition import org.springframework.transaction.TransactionStatus @@ -223,6 +227,9 @@ abstract class AbstractSpringTest : AbstractTransactionalTest() { @Autowired lateinit var allCachesProvider: AllCachesProvider + @Autowired + lateinit var objectMapper: ObjectMapper + @BeforeEach fun clearCaches() { allCachesProvider.getAllCaches().forEach { cacheName -> @@ -284,4 +291,19 @@ abstract class AbstractSpringTest : AbstractTransactionalTest() { open fun moveCurrentDate(duration: Duration) { currentDateProvider.move(duration) } + + protected inline fun ResultActions.getContent(): T { + val stringContent = this.andGetContentAsString + return objectMapper.readValue(stringContent) + } + + protected fun ResultActions.getIdFromResponse(): Long { + this.andIsOk + val response: Map = getContent() + try { + return (response["id"] as Number).toLong() + } catch (e: Exception) { + throw Error("Response does not contain id", e) + } + } } From 8ef69fe35ea0556e420df7759700502407863618 Mon Sep 17 00:00:00 2001 From: Jan Cizmar Date: Tue, 25 Feb 2025 16:12:08 +0100 Subject: [PATCH 03/16] feat: Backend for creating plan with keys/seats metric & refactoring --- .../kotlin/io/tolgee/events/OnOrganizationNameUpdated.kt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 backend/data/src/main/kotlin/io/tolgee/events/OnOrganizationNameUpdated.kt diff --git a/backend/data/src/main/kotlin/io/tolgee/events/OnOrganizationNameUpdated.kt b/backend/data/src/main/kotlin/io/tolgee/events/OnOrganizationNameUpdated.kt new file mode 100644 index 0000000000..5dcfe564c9 --- /dev/null +++ b/backend/data/src/main/kotlin/io/tolgee/events/OnOrganizationNameUpdated.kt @@ -0,0 +1,8 @@ +package io.tolgee.events + +import io.tolgee.model.Organization + +class OnOrganizationNameUpdated( + val oldName: String, + val organization: Organization, +) From b02c362c567c5a2724faae553faf9dd78c184277 Mon Sep 17 00:00:00 2001 From: Jan Cizmar Date: Tue, 25 Feb 2025 17:42:56 +0100 Subject: [PATCH 04/16] feat: UI for creating cloud plan > first piece --- .run/Frontend localhost.run.xml | 4 +- e2e/cypress/support/dataCyType.d.ts | 4 +- .../src/constants/GlobalValidationSchema.tsx | 6 +- .../AdministrationEePlanCreateView.tsx | 1 + .../components/planForm/CloudPlanFormBase.tsx | 3 + .../components/planForm/EePlanForm.tsx | 46 +- .../planForm/fields/CloudPlanFields.tsx | 138 +-- .../fields/CloudPlanIncludedUsage.tsx | 79 ++ .../fields/CloudPlanMetricTypeSelectField.tsx | 50 + .../planForm/fields/CloudPlanPrices.tsx | 69 +- .../fields/CloudPlanPricesAndLimits.tsx | 41 +- .../fields/CloudPlanTypeSelectField.tsx | 56 + .../fields/PlanEnabledFeaturesField.tsx | 60 ++ .../fields/StripeProductSelectField.tsx | 54 + .../planForm/getCloudPlanInitialValues.ts | 10 +- .../planForm/useCloudPlanFormValues.ts | 12 + webapp/src/service/apiSchema.generated.ts | 3 + .../src/service/billingApiSchema.generated.ts | 955 +++--------------- 18 files changed, 524 insertions(+), 1067 deletions(-) create mode 100644 webapp/src/ee/billing/administration/subscriptionPlans/components/planForm/fields/CloudPlanIncludedUsage.tsx create mode 100644 webapp/src/ee/billing/administration/subscriptionPlans/components/planForm/fields/CloudPlanMetricTypeSelectField.tsx create mode 100644 webapp/src/ee/billing/administration/subscriptionPlans/components/planForm/fields/CloudPlanTypeSelectField.tsx create mode 100644 webapp/src/ee/billing/administration/subscriptionPlans/components/planForm/fields/PlanEnabledFeaturesField.tsx create mode 100644 webapp/src/ee/billing/administration/subscriptionPlans/components/planForm/fields/StripeProductSelectField.tsx create mode 100644 webapp/src/ee/billing/administration/subscriptionPlans/components/planForm/useCloudPlanFormValues.ts diff --git a/.run/Frontend localhost.run.xml b/.run/Frontend localhost.run.xml index 7dc8b2b7db..cd78cf5baa 100644 --- a/.run/Frontend localhost.run.xml +++ b/.run/Frontend localhost.run.xml @@ -1,6 +1,6 @@ - +