-
-
Notifications
You must be signed in to change notification settings - Fork 308
feat: plans migration #3216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dkrizan
wants to merge
37
commits into
main
Choose a base branch
from
danielkrizan/plan-migration
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
feat: plans migration #3216
Changes from 36 commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
a5a0cbe
chore: create plan migration endpoint
dkrizan a090d1c
feat: cloud plans migration controller + UI
dkrizan 00561df
feat: self-hosted migrations controller and UI
dkrizan 0779d66
chore: test plan migration
dkrizan d2bef84
draft: migration history
dkrizan 1962d00
chore: option to delete selfhosted plan migration, handle customer up…
dkrizan e902d3f
chore: real stripe test to schedule update and preview update
dkrizan fc52e06
feat: self-hosted plans - migrated subscriptions list
dkrizan 4f7691f
feat: send plan change notice when migrated
dkrizan 075ee69
chore: migration history refactored
dkrizan bd2655d
chore: migrator cache fix
dkrizan 2769f77
chore: e2e tests - administration plan migrations
dkrizan 83efb86
chore: test fix
dkrizan 588c36d
chore: migration form refactored
dkrizan f6f901f
feat: allow upgrade free plans too
dkrizan 44271f8
chore: release schedule on subscription update
dkrizan a4b61a9
chore: check-translations fix
dkrizan 02cac56
feat: migration email content updated
dkrizan c044936
chore: CR fixes
dkrizan a02b0bf
chore: plan migration form refactored
dkrizan 3b95305
chore: plan migration edit form refactored
dkrizan 1cb0e3f
chore: CR refactors
dkrizan 7145e10
chore: internal properties controller refactor
dkrizan 4fb3159
chore: migration history refactored (renamed to migration record)
dkrizan 69f6f64
chore: type
dkrizan 6c48d28
fix: PlanMigration chip code improvements
dkrizan e8287d8
chore: coderabbit fixes
dkrizan 673407f
chore: billingSchema updated
dkrizan f5cb4ad
chore: coderabbitai fixes
dkrizan 6bb614c
chore: refactor plan migration create form
dkrizan c06de72
chore: coderabbit improvements
dkrizan c0eebc6
chore: coderabbit improvements 2
dkrizan e69fd5e
chore: coderabbit improvements 2
dkrizan 1cb9b05
chore: error message for missing plan migration
dkrizan 962e0d2
chore: schemas updated
dkrizan 42559b8
chore: schemas updated
dkrizan 9d162ab
chore: coderabbit
dkrizan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -113,3 +113,24 @@ notifications.email.security-settings-link=Check your security settings <a href= | |
| notifications.email.mfa.MFA_ENABLED=Multi-factor authentication has been enabled for your account. | ||
| notifications.email.mfa.MFA_DISABLED=Multi-factor authentication has been disabled for your account. | ||
| notifications.email.password-changed=Password has been changed for your account. | ||
|
|
||
| notifications.email.plan-migration-subject=Upcoming update to your Tolgee subscription plan | ||
| notifications.email.plan-migration-body=Dear {0},<br/>\ | ||
| <br/>\ | ||
| Earlier this year, we introduced a new pricing structure for new Tolgee customers while keeping existing users on their current plans. We’re now moving all subscriptions to the new plans to make things simpler and fair for everyone.<br/>\ | ||
| <br/>\ | ||
| In the new structure, translation strings have been replaced with keys and seats to better reflect how Tolgee is used. You can view the updated pricing here <a href="https://tolgee.io/pricing">https://tolgee.io/pricing</a>.<br/>\ | ||
| <br/>\ | ||
| Your current {1} plan will automatically switch to the new {2} plan at your next renewal, whether monthly or yearly, depending on your subscription. If you’d like to explore other subscriptions options, you can do so anytime in the <a href="{3}">Subscriptions</a> section within the Tolgee platform.<br/>\ | ||
| <br/>\ | ||
| Thank you for your continued trust and support!<br/>\ | ||
| <br/>\ | ||
| P.S. I understand these changes may cause discomfort and not accommodate everyone’s circumstances. If this materially impacts your business, I warmly invite you to contact me directly for a personal dialogue regarding your concerns. You can reach me at:<br/>\ | ||
| <ul>\ | ||
| <li>Email: [email protected]</li>\ | ||
| <li><a href="https://tolg.ee/slack">Tolgee Slack</a></li>\ | ||
| <li>Schedule a meeting via Calendly <a href="https://calendly.com/jancizmar/quick-chat-with-jan?month={4}">https://calendly.com/jancizmar/quick-chat-with-jan?month={4}</a></li>\ | ||
| </ul>\ | ||
| Warm regards,<br/>\ | ||
| Jan<br/>\ | ||
| CEO, Tolgee | ||
31 changes: 4 additions & 27 deletions
31
backend/development/src/main/kotlin/io/tolgee/controllers/internal/PropertiesController.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,47 +1,24 @@ | ||
| package io.tolgee.controllers.internal | ||
|
|
||
| import io.tolgee.configuration.tolgee.E2eRuntimeMutable | ||
| import io.tolgee.configuration.tolgee.TolgeeProperties | ||
| import io.tolgee.dtos.request.SetPropertyDto | ||
| import io.tolgee.exceptions.BadRequestException | ||
| import io.tolgee.exceptions.NotFoundException | ||
| import io.tolgee.facade.InternalPropertiesSetterFacade | ||
| import jakarta.validation.Valid | ||
| import org.springframework.transaction.annotation.Transactional | ||
| import org.springframework.web.bind.annotation.PutMapping | ||
| import org.springframework.web.bind.annotation.RequestBody | ||
| import kotlin.reflect.KMutableProperty1 | ||
| import kotlin.reflect.KProperty1 | ||
| import kotlin.reflect.full.declaredMemberProperties | ||
| import kotlin.reflect.full.hasAnnotation | ||
|
|
||
| @InternalController(["internal/properties"]) | ||
| class PropertiesController( | ||
| val tolgeeProperties: TolgeeProperties, | ||
| private val tolgeeProperties: TolgeeProperties, | ||
| private val internalPropertiesSetterFacade: InternalPropertiesSetterFacade, | ||
| ) { | ||
| @PutMapping(value = ["/set"]) | ||
| @Transactional | ||
| fun setProperty( | ||
| @RequestBody @Valid | ||
| setPropertyDto: SetPropertyDto, | ||
| ) { | ||
| val name = setPropertyDto.name | ||
| var instance: Any = tolgeeProperties | ||
| name.split(".").let { namePath -> | ||
| namePath.forEachIndexed { idx, property -> | ||
| val isLast = idx == namePath.size - 1 | ||
| val props = instance::class.declaredMemberProperties | ||
| val prop = props.find { it.name == property } ?: throw NotFoundException() | ||
| if (isLast) { | ||
| (prop as? KMutableProperty1<Any, Any?>)?.let { | ||
| if (!it.hasAnnotation<E2eRuntimeMutable>()) { | ||
| io.tolgee.constants.Message.PROPERTY_NOT_MUTABLE | ||
| } | ||
| it.set(instance, setPropertyDto.value) | ||
| return | ||
| } ?: throw BadRequestException(io.tolgee.constants.Message.PROPERTY_NOT_MUTABLE) | ||
| } | ||
| instance = (prop as KProperty1<Any, Any?>).get(instance)!! | ||
| } | ||
| } | ||
| internalPropertiesSetterFacade.setProperty(tolgeeProperties, setPropertyDto) | ||
| } | ||
| } |
42 changes: 42 additions & 0 deletions
42
backend/development/src/main/kotlin/io/tolgee/facade/InternalPropertiesSetterFacade.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package io.tolgee.facade | ||
|
|
||
| import io.tolgee.configuration.tolgee.E2eRuntimeMutable | ||
| import io.tolgee.dtos.request.SetPropertyDto | ||
| import io.tolgee.exceptions.BadRequestException | ||
| import io.tolgee.exceptions.NotFoundException | ||
| import org.springframework.stereotype.Component | ||
| import kotlin.reflect.KMutableProperty1 | ||
| import kotlin.reflect.KProperty1 | ||
| import kotlin.reflect.full.declaredMemberProperties | ||
| import kotlin.reflect.full.hasAnnotation | ||
|
|
||
| @Component | ||
| class InternalPropertiesSetterFacade { | ||
| fun setProperty( | ||
| root: Any, | ||
| setPropertyDto: SetPropertyDto, | ||
| onSet: (() -> Unit)? = null, | ||
| ) { | ||
| val name = setPropertyDto.name | ||
| var instance: Any = root | ||
| name.split(".").let { namePath -> | ||
| namePath.forEachIndexed { idx, property -> | ||
| val isLast = idx == namePath.size - 1 | ||
| val props = instance::class.declaredMemberProperties | ||
| val prop = props.find { it.name == property } ?: throw NotFoundException() | ||
| if (isLast) { | ||
| (prop as? KMutableProperty1<Any, Any?>)?.let { | ||
| if (!it.hasAnnotation<E2eRuntimeMutable>()) { | ||
| io.tolgee.constants.Message.PROPERTY_NOT_MUTABLE | ||
| } | ||
| it.set(instance, setPropertyDto.value) | ||
| onSet?.invoke() | ||
| return | ||
| } ?: throw BadRequestException(io.tolgee.constants.Message.PROPERTY_NOT_MUTABLE) | ||
dkrizan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| instance = (prop as KProperty1<Any, Any?>).get(instance) | ||
| ?: throw NotFoundException() | ||
| } | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { styled, Tooltip, tooltipClasses, TooltipProps } from '@mui/material'; | ||
|
|
||
| export const FullWidthTooltip = styled( | ||
| ({ className, ...props }: TooltipProps) => ( | ||
| <Tooltip {...props} classes={{ popper: className }} /> | ||
| ) | ||
| )({ | ||
| [`& .${tooltipClasses.tooltip}`]: { | ||
| maxWidth: 'none', | ||
| }, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.