Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function PageSettingsGeneralFeature() {
accessibility: database?.accessibility,
annotations_groups: database?.annotations_groups?.map((group) => group.id),
labels_groups: database?.labels_groups?.map((group) => group.id),
apply_immediately: false,
},
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { type FieldValues, FormProvider, useForm } from 'react-hook-form'
import { useParams } from 'react-router-dom'
import { type DatabaseEditRequest } from 'qovery-typescript-axios'
import { useEnvironment } from '@qovery/domains/environments/feature'
import { type Database } from '@qovery/domains/services/data-access'
import { useEditService, useService } from '@qovery/domains/services/feature'
import { buildEditServicePayload } from '@qovery/shared/util-services'
import PageSettingsResources from '../../ui/page-settings-resources/page-settings-resources'

export const handleSubmit = (data: FieldValues, database: Database) => {
const cloneDatabase = Object.assign({}, database)

cloneDatabase.cpu = data['cpu']
cloneDatabase.memory = Number(data['memory'])
cloneDatabase.storage = Number(data['storage'])
cloneDatabase.instance_type = data['instance_type']

return cloneDatabase
export const handleSubmit = (data: FieldValues, database: Database): Partial<DatabaseEditRequest> => {
return {
cpu: data['cpu'],
memory: Number(data['memory']),
storage: Number(data['storage']),
instance_type: data['instance_type'],
apply_immediately: data['apply_immediately'],
}
}

export function PageSettingsResourcesFeature() {
Expand All @@ -36,6 +36,7 @@ export function PageSettingsResourcesFeature() {
storage: database?.storage,
cpu: database?.cpu || 10,
instance_type: database?.instance_type,
apply_immediately: false,
},
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { match } from 'ts-pattern'
import { AnnotationSetting, LabelSetting } from '@qovery/domains/organizations/feature'
import { type Database } from '@qovery/domains/services/data-access'
import { GeneralSetting } from '@qovery/domains/services/feature'
import { SettingsHeading } from '@qovery/shared/console-shared'
import { ApplyImmediatelyCheckbox, SettingsHeading } from '@qovery/shared/console-shared'
import { type Value } from '@qovery/shared/interfaces'
import {
Button,
Expand Down Expand Up @@ -150,22 +150,7 @@ export function PageSettingsGeneral({
)}

{databaseMode === DatabaseModeEnum.MANAGED && formState.dirtyFields['version'] && (
<Callout.Root color="yellow">
<Callout.Icon>
<Icon iconName="circle-info" />
</Callout.Icon>
<Callout.Text className="text-neutral-350">
Once triggered, the update will be managed by your cloud provider and applied during the
configured maintenance window. Moreover, the operation might cause a service interruption.{' '}
<ExternalLink
className="mt-1"
href="https://www.qovery.com/docs/configuration/database#applying-changes-to-a-managed-database"
size="xs"
>
Have a look at the documentation first
</ExternalLink>
</Callout.Text>
</Callout.Root>
<ApplyImmediatelyCheckbox />
)}
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { DatabaseModeEnum } from 'qovery-typescript-axios'
import { type FormEventHandler } from 'react'
import { useFormContext } from 'react-hook-form'
import { type Database } from '@qovery/domains/services/data-access'
import { DatabaseSettingsResources } from '@qovery/shared/console-shared'
import { SettingsHeading } from '@qovery/shared/console-shared'
import { ApplyImmediatelyCheckbox, DatabaseSettingsResources, SettingsHeading } from '@qovery/shared/console-shared'
import { Button, Callout, Heading, Icon, Section } from '@qovery/shared/ui'

export interface PageSettingsResourcesProps {
Expand Down Expand Up @@ -55,6 +54,11 @@ export function PageSettingsResources(props: PageSettingsResourcesProps) {
displayStorageWarning={displayStorageWarning}
isSetting
/>
{(displayInstanceTypesWarning || displayStorageWarning) && (
<div className="mt-3">
<ApplyImmediatelyCheckbox />
</div>
)}
</Section>

<div className="flex justify-end">
Expand Down
1 change: 1 addition & 0 deletions libs/shared/console-shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ export * from './lib/application-settings/ui/application-settings-resources/appl
export * from './lib/application-settings/ui/application-settings-healthchecks/application-settings-healthchecks'
export * from './lib/application-settings/utils/probe-formatted'
export * from './lib/settings-heading/settings-heading'
export * from './lib/apply-immediately-checkbox/apply-immediately-checkbox'
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { FormProvider, useForm } from 'react-hook-form'
import { renderWithProviders, screen } from '@qovery/shared/util-tests'
import { ApplyImmediatelyCheckbox } from './apply-immediately-checkbox'

function Wrapper({ children, defaultValues = {} }: { children: React.ReactNode; defaultValues?: any }) {
const methods = useForm({
defaultValues: {
apply_immediately: false,
...defaultValues,
},
})

return <FormProvider {...methods}>{children}</FormProvider>
}

describe('ApplyImmediatelyCheckbox', () => {
it('should render successfully', () => {
const { baseElement } = renderWithProviders(
<Wrapper>
<ApplyImmediatelyCheckbox />
</Wrapper>
)
expect(baseElement).toBeTruthy()
})

it('should display warning when checkbox is checked', async () => {
const { userEvent } = renderWithProviders(
<Wrapper>
<ApplyImmediatelyCheckbox />
</Wrapper>
)

const checkbox = screen.getByRole('checkbox')
await userEvent.click(checkbox)

expect(screen.getByTestId('apply-immediately-warning')).toBeInTheDocument()
})

it('should not display warning when checkbox is unchecked', () => {
renderWithProviders(
<Wrapper>
<ApplyImmediatelyCheckbox />
</Wrapper>
)

expect(screen.queryByTestId('apply-immediately-warning')).not.toBeInTheDocument()
})

it('should be disabled when disabled prop is true', () => {
renderWithProviders(
<Wrapper>
<ApplyImmediatelyCheckbox disabled />
</Wrapper>
)

const checkbox = screen.getByRole('checkbox')
expect(checkbox).toBeDisabled()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Controller, useFormContext } from 'react-hook-form'
import { Callout, Checkbox, ExternalLink, Icon } from '@qovery/shared/ui'

export interface ApplyImmediatelyCheckboxProps {
disabled?: boolean
}

export function ApplyImmediatelyCheckbox({ disabled = false }: ApplyImmediatelyCheckboxProps) {
const { control, watch } = useFormContext()

const applyImmediately = watch('apply_immediately')

return (
<div className="space-y-3">
<Controller
name="apply_immediately"
control={control}
render={({ field }) => (
<label className="flex cursor-pointer items-start gap-3">
<Checkbox checked={field.value} onCheckedChange={field.onChange} disabled={disabled} className="mt-0.5" />
<div className="flex-1">
<span className="text-sm font-medium text-neutral-400">Apply changes immediately</span>
<p className="mt-1 text-xs text-neutral-350">
Apply the changes immediately instead of waiting for the maintenance window.
</p>
</div>
</label>
)}
/>

<Callout.Root color="yellow" data-testid="maintenance-warning">
<Callout.Icon>
<Icon iconName={applyImmediately ? 'triangle-exclamation' : 'circle-info'} iconStyle="regular" />
</Callout.Icon>
<Callout.Text className="text-neutral-400">
<div className="space-y-3">
<div>
Once triggered, the update will be managed by your cloud provider and applied during the configured
maintenance window. Moreover, the operation might cause a service interruption.{' '}
<ExternalLink
className="mt-1"
href="https://www.qovery.com/docs/configuration/database#applying-changes-to-a-managed-database"
>
Have a look at the documentation first
</ExternalLink>
</div>
{applyImmediately && (
<div className="border-t border-yellow-400/30 pt-3" data-testid="apply-immediately-warning">
<span className="font-medium">Warning:</span> Applying changes immediately may cause a brief service
interruption. The operation will be performed outside of your configured maintenance window.
</div>
)}
</div>
</Callout.Text>
</Callout.Root>
</div>
)
}

export default ApplyImmediatelyCheckbox
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { match } from 'ts-pattern'
import { useEnvironment } from '@qovery/domains/environments/feature'
import { type Database } from '@qovery/domains/services/data-access'
import { CLUSTER_SETTINGS_RESOURCES_URL, CLUSTER_SETTINGS_URL, CLUSTER_URL } from '@qovery/shared/routes'
import { Callout, ExternalLink, Icon, InputText, Link, inputSizeUnitRules } from '@qovery/shared/ui'
import { InputText, Link, inputSizeUnitRules } from '@qovery/shared/ui'
import SettingsResourcesInstanceTypesFeature from '../../feature/settings-resources-instance-types-feature/setting-resources-instance-types-feature'

export interface DatabaseSettingsResourcesProps {
Expand Down Expand Up @@ -176,23 +176,6 @@ export function DatabaseSettingsResources({
/>
)}
/>
{displayStorageWarning && (
<Callout.Root className="mt-3" color="yellow">
<Callout.Icon>
<Icon iconName="circle-info" iconStyle="regular" />
</Callout.Icon>
<Callout.Text className="text-neutral-350">
Once triggered, the update will be managed by your cloud provider and applied during the configured
maintenance window. Moreover, the operation might cause a service interruption.{' '}
<ExternalLink
className="mt-1"
href="https://www.qovery.com/docs/configuration/database#applying-changes-to-a-managed-database"
>
Have a look at the documentation first
</ExternalLink>
</Callout.Text>
</Callout.Root>
)}
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Controller, useFormContext } from 'react-hook-form'
import { type Value } from '@qovery/shared/interfaces'
import { Callout, ExternalLink, Icon, InputSelect } from '@qovery/shared/ui'
import { InputSelect } from '@qovery/shared/ui'

export interface SettingsResourcesInstanceTypesProps {
databaseInstanceTypes?: Value[]
Expand All @@ -14,43 +14,24 @@ export function SettingsResourcesInstanceTypes({
const { control } = useFormContext()

return (
<>
<Controller
name="instance_type"
control={control}
rules={{
required: 'Please select an instance type',
}}
render={({ field, fieldState: { error } }) => (
<InputSelect
isSearchable
onChange={field.onChange}
value={field.value}
label="Instance type"
error={error?.message}
options={databaseInstanceTypes}
hint="The chosen instance type has a direct impact on your cloud provider cost."
/>
)}
/>
{displayWarning && (
<Callout.Root className="mt-3" color="yellow" data-testid="settings-resources-instance-types-warning">
<Callout.Icon>
<Icon iconName="circle-info" iconStyle="regular" />
</Callout.Icon>
<Callout.Text className="text-neutral-350">
Once triggered, the update will be managed by your cloud provider and applied during the configured
maintenance window. Moreover, the operation might cause a service interruption.{' '}
<ExternalLink
className="mt-1"
href="https://www.qovery.com/docs/configuration/database#applying-changes-to-a-managed-database"
>
Have a look at the documentation first
</ExternalLink>
</Callout.Text>
</Callout.Root>
<Controller
name="instance_type"
control={control}
rules={{
required: 'Please select an instance type',
}}
render={({ field, fieldState: { error } }) => (
<InputSelect
isSearchable
onChange={field.onChange}
value={field.value}
label="Instance type"
error={error?.message}
options={databaseInstanceTypes}
hint="The chosen instance type has a direct impact on your cloud provider cost."
/>
)}
</>
/>
)
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"mermaid": "^11.6.0",
"monaco-editor": "0.53.0",
"posthog-js": "^1.260.1",
"qovery-typescript-axios": "^1.1.821",
"qovery-typescript-axios": "^1.1.822",
"react": "18.3.1",
"react-country-flag": "^3.0.2",
"react-datepicker": "^4.12.0",
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5679,7 +5679,7 @@ __metadata:
prettier: ^3.2.5
prettier-plugin-tailwindcss: ^0.5.14
pretty-quick: ^4.0.0
qovery-typescript-axios: ^1.1.821
qovery-typescript-axios: ^1.1.822
qovery-ws-typescript-axios: ^0.1.420
react: 18.3.1
react-country-flag: ^3.0.2
Expand Down Expand Up @@ -24520,12 +24520,12 @@ __metadata:
languageName: node
linkType: hard

"qovery-typescript-axios@npm:^1.1.821":
version: 1.1.821
resolution: "qovery-typescript-axios@npm:1.1.821"
"qovery-typescript-axios@npm:^1.1.822":
version: 1.1.822
resolution: "qovery-typescript-axios@npm:1.1.822"
dependencies:
axios: 1.12.2
checksum: e51d1d3b1d96d8f55e6e9522efbb86d47994c63bcf11b8fb6240e45b9d396d2c198255ec2e43c6a7a15b8c0bbcd9c442aaaa3daeb51f117e9f2cd338ddf024dd
checksum: 8b36527588e8c40002f09fdac722df24eb49e38a9dd2d13e14b89f47498346ab2dd4efec2b16258487080786d4459363c8e3fb9ce746aee952f46fb8b638e7fd
languageName: node
linkType: hard

Expand Down
Loading