mirror of
https://github.com/enso-org/enso.git
synced 2024-11-26 17:06:48 +03:00
Fix skipping creating a user if we don't change the default name (#11013)
Closes: enso-org/cloud-v2#1473 This PR fixes a bug introduced in #10946
This commit is contained in:
parent
7b4b635fa8
commit
1fdaf37add
@ -9,13 +9,14 @@ import * as portal from '#/components/Portal'
|
|||||||
import * as suspense from '#/components/Suspense'
|
import * as suspense from '#/components/Suspense'
|
||||||
|
|
||||||
import * as mergeRefs from '#/utilities/mergeRefs'
|
import * as mergeRefs from '#/utilities/mergeRefs'
|
||||||
import * as twv from '#/utilities/tailwindVariants'
|
|
||||||
|
|
||||||
|
import type { VariantProps } from '#/utilities/tailwindVariants'
|
||||||
|
import { tv } from '#/utilities/tailwindVariants'
|
||||||
import * as dialogProvider from './DialogProvider'
|
import * as dialogProvider from './DialogProvider'
|
||||||
import * as dialogStackProvider from './DialogStackProvider'
|
import * as dialogStackProvider from './DialogStackProvider'
|
||||||
import type * as types from './types'
|
import type * as types from './types'
|
||||||
import * as utlities from './utilities'
|
import * as utlities from './utilities'
|
||||||
import * as variants from './variants'
|
import { DIALOG_BACKGROUND } from './variants'
|
||||||
|
|
||||||
// =================
|
// =================
|
||||||
// === Constants ===
|
// === Constants ===
|
||||||
@ -25,10 +26,10 @@ import * as variants from './variants'
|
|||||||
*/
|
*/
|
||||||
export interface DialogProps
|
export interface DialogProps
|
||||||
extends types.DialogProps,
|
extends types.DialogProps,
|
||||||
Omit<twv.VariantProps<typeof DIALOG_STYLES>, 'scrolledToTop'> {}
|
Omit<VariantProps<typeof DIALOG_STYLES>, 'scrolledToTop'> {}
|
||||||
|
|
||||||
const OVERLAY_STYLES = twv.tv({
|
const OVERLAY_STYLES = tv({
|
||||||
base: 'fixed inset-0 isolate flex items-center justify-center bg-black/[25%]',
|
base: 'fixed inset-0 isolate flex items-center justify-center bg-primary/20',
|
||||||
variants: {
|
variants: {
|
||||||
isEntering: { true: 'animate-in fade-in duration-200 ease-out' },
|
isEntering: { true: 'animate-in fade-in duration-200 ease-out' },
|
||||||
isExiting: { true: 'animate-out fade-out duration-200 ease-in' },
|
isExiting: { true: 'animate-out fade-out duration-200 ease-in' },
|
||||||
@ -36,17 +37,23 @@ const OVERLAY_STYLES = twv.tv({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const MODAL_STYLES = twv.tv({
|
const MODAL_STYLES = tv({
|
||||||
base: 'fixed inset-0 flex items-center justify-center text-center text-xs text-primary p-4',
|
base: 'fixed inset-0 flex items-center justify-center text-xs text-primary',
|
||||||
variants: {
|
variants: {
|
||||||
isEntering: { true: 'animate-in slide-in-from-top-1 ease-out duration-200' },
|
isEntering: { true: 'animate-in ease-out duration-200' },
|
||||||
isExiting: { true: 'animate-out slide-out-to-top-1 ease-in duration-200' },
|
isExiting: { true: 'animate-out ease-in duration-200' },
|
||||||
|
type: { modal: '', fullscreen: 'p-3.5' },
|
||||||
},
|
},
|
||||||
|
compoundVariants: [
|
||||||
|
{ type: 'modal', isEntering: true, class: 'slide-in-from-top-1' },
|
||||||
|
{ type: 'modal', isExiting: true, class: 'slide-out-to-top-1' },
|
||||||
|
{ type: 'fullscreen', isEntering: true, class: 'zoom-in-[1.015]' },
|
||||||
|
{ type: 'fullscreen', isExiting: true, class: 'zoom-out-[1.015]' },
|
||||||
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
const DIALOG_STYLES = twv.tv({
|
const DIALOG_STYLES = tv({
|
||||||
extend: variants.DIALOG_STYLES,
|
base: DIALOG_BACKGROUND({ className: 'w-full flex flex-col text-left align-middle shadow-xl' }),
|
||||||
base: 'w-full overflow-y-auto',
|
|
||||||
variants: {
|
variants: {
|
||||||
type: {
|
type: {
|
||||||
modal: {
|
modal: {
|
||||||
@ -74,6 +81,16 @@ const DIALOG_STYLES = twv.tv({
|
|||||||
content: 'isolate',
|
content: 'isolate',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
rounded: {
|
||||||
|
none: { base: '' },
|
||||||
|
small: { base: 'rounded-sm' },
|
||||||
|
medium: { base: 'rounded-md' },
|
||||||
|
large: { base: 'rounded-lg' },
|
||||||
|
xlarge: { base: 'rounded-xl' },
|
||||||
|
xxlarge: { base: 'rounded-2xl', content: 'scroll-offset-edge-2xl' },
|
||||||
|
xxxlarge: { base: 'rounded-3xl', content: 'scroll-offset-edge-4xl' },
|
||||||
|
xxxxlarge: { base: 'rounded-4xl', content: 'scroll-offset-edge-6xl' },
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* The size of the dialog.
|
* The size of the dialog.
|
||||||
* Only applies to the `modal` type.
|
* Only applies to the `modal` type.
|
||||||
@ -120,6 +137,7 @@ const DIALOG_STYLES = twv.tv({
|
|||||||
hideCloseButton: false,
|
hideCloseButton: false,
|
||||||
size: 'medium',
|
size: 'medium',
|
||||||
padding: 'medium',
|
padding: 'medium',
|
||||||
|
rounded: 'xxlarge',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -146,6 +164,7 @@ export function Dialog(props: DialogProps) {
|
|||||||
rounded,
|
rounded,
|
||||||
padding = type === 'modal' ? 'medium' : 'xlarge',
|
padding = type === 'modal' ? 'medium' : 'xlarge',
|
||||||
fitContent,
|
fitContent,
|
||||||
|
variants = DIALOG_STYLES,
|
||||||
...ariaDialogProps
|
...ariaDialogProps
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
@ -155,11 +174,13 @@ export function Dialog(props: DialogProps) {
|
|||||||
* Handles the scroll event on the dialog content.
|
* Handles the scroll event on the dialog content.
|
||||||
*/
|
*/
|
||||||
const handleScroll = (scrollTop: number) => {
|
const handleScroll = (scrollTop: number) => {
|
||||||
if (scrollTop > 0) {
|
React.startTransition(() => {
|
||||||
setIsScrolledToTop(false)
|
if (scrollTop > 0) {
|
||||||
} else {
|
setIsScrolledToTop(false)
|
||||||
setIsScrolledToTop(true)
|
} else {
|
||||||
}
|
setIsScrolledToTop(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const dialogId = aria.useId()
|
const dialogId = aria.useId()
|
||||||
@ -169,7 +190,7 @@ export function Dialog(props: DialogProps) {
|
|||||||
const overlayState = React.useRef<aria.OverlayTriggerState | null>(null)
|
const overlayState = React.useRef<aria.OverlayTriggerState | null>(null)
|
||||||
const root = portal.useStrictPortalContext()
|
const root = portal.useStrictPortalContext()
|
||||||
|
|
||||||
const styles = DIALOG_STYLES({
|
const styles = variants({
|
||||||
className,
|
className,
|
||||||
type,
|
type,
|
||||||
rounded,
|
rounded,
|
||||||
@ -200,11 +221,7 @@ export function Dialog(props: DialogProps) {
|
|||||||
return (
|
return (
|
||||||
<aria.ModalOverlay
|
<aria.ModalOverlay
|
||||||
className={({ isEntering, isExiting }) =>
|
className={({ isEntering, isExiting }) =>
|
||||||
OVERLAY_STYLES({
|
OVERLAY_STYLES({ isEntering, isExiting, blockInteractions: !isDismissable })
|
||||||
isEntering,
|
|
||||||
isExiting,
|
|
||||||
blockInteractions: !isDismissable,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
isDismissable={isDismissable}
|
isDismissable={isDismissable}
|
||||||
isKeyboardDismissDisabled={isKeyboardDismissDisabled}
|
isKeyboardDismissDisabled={isKeyboardDismissDisabled}
|
||||||
@ -218,7 +235,7 @@ export function Dialog(props: DialogProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<aria.Modal
|
<aria.Modal
|
||||||
className={MODAL_STYLES}
|
className={({ isEntering, isExiting }) => MODAL_STYLES({ type, isEntering, isExiting })}
|
||||||
isDismissable={isDismissable}
|
isDismissable={isDismissable}
|
||||||
isKeyboardDismissDisabled={isKeyboardDismissDisabled}
|
isKeyboardDismissDisabled={isKeyboardDismissDisabled}
|
||||||
UNSTABLE_portalContainer={root}
|
UNSTABLE_portalContainer={root}
|
||||||
@ -252,25 +269,23 @@ export function Dialog(props: DialogProps) {
|
|||||||
{(opts) => {
|
{(opts) => {
|
||||||
return (
|
return (
|
||||||
<dialogProvider.DialogProvider value={{ close: opts.close, dialogId }}>
|
<dialogProvider.DialogProvider value={{ close: opts.close, dialogId }}>
|
||||||
{((!hideCloseButton && closeButton !== 'floating') || title != null) && (
|
<aria.Header className={styles.header({ scrolledToTop: isScrolledToTop })}>
|
||||||
<aria.Header className={styles.header({ scrolledToTop: isScrolledToTop })}>
|
<ariaComponents.CloseButton
|
||||||
<ariaComponents.CloseButton
|
className={styles.closeButton()}
|
||||||
className={styles.closeButton()}
|
onPress={opts.close}
|
||||||
onPress={opts.close}
|
/>
|
||||||
/>
|
|
||||||
|
|
||||||
{title != null && (
|
{title != null && (
|
||||||
<ariaComponents.Text.Heading
|
<ariaComponents.Text.Heading
|
||||||
id={titleId}
|
id={titleId}
|
||||||
level={2}
|
level={2}
|
||||||
className={styles.heading()}
|
className={styles.heading()}
|
||||||
weight="semibold"
|
weight="semibold"
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</ariaComponents.Text.Heading>
|
</ariaComponents.Text.Heading>
|
||||||
)}
|
)}
|
||||||
</aria.Header>
|
</aria.Header>
|
||||||
)}
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
ref={(ref) => {
|
ref={(ref) => {
|
||||||
|
@ -14,19 +14,4 @@ export const DIALOG_BACKGROUND = twv.tv({
|
|||||||
export const DIALOG_STYLES = twv.tv({
|
export const DIALOG_STYLES = twv.tv({
|
||||||
extend: DIALOG_BACKGROUND,
|
extend: DIALOG_BACKGROUND,
|
||||||
base: 'flex flex-col text-left align-middle shadow-xl',
|
base: 'flex flex-col text-left align-middle shadow-xl',
|
||||||
variants: {
|
|
||||||
rounded: {
|
|
||||||
none: '',
|
|
||||||
small: 'rounded-sm',
|
|
||||||
medium: 'rounded-md',
|
|
||||||
large: 'rounded-lg',
|
|
||||||
xlarge: 'rounded-xl',
|
|
||||||
xxlarge: 'rounded-2xl',
|
|
||||||
xxxlarge: 'rounded-3xl',
|
|
||||||
xxxxlarge: 'rounded-4xl',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
defaultVariants: {
|
|
||||||
rounded: 'xxlarge',
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
@ -7,6 +7,8 @@ import { useAuth } from '#/providers/AuthProvider'
|
|||||||
import { useRemoteBackendStrict } from '#/providers/BackendProvider'
|
import { useRemoteBackendStrict } from '#/providers/BackendProvider'
|
||||||
import { useText } from '#/providers/TextProvider'
|
import { useText } from '#/providers/TextProvider'
|
||||||
import { Plan, PLANS } from '#/services/Backend'
|
import { Plan, PLANS } from '#/services/Backend'
|
||||||
|
import type { VariantProps } from '#/utilities/tailwindVariants'
|
||||||
|
import { tv } from '#/utilities/tailwindVariants'
|
||||||
import { Card } from './components'
|
import { Card } from './components'
|
||||||
import { getComponentPerPlan } from './getComponentForPlan'
|
import { getComponentPerPlan } from './getComponentForPlan'
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ interface CreateCheckoutSessionMutation {
|
|||||||
/**
|
/**
|
||||||
* Props for {@link PlanSelector}
|
* Props for {@link PlanSelector}
|
||||||
*/
|
*/
|
||||||
export interface PlanSelectorProps {
|
export interface PlanSelectorProps extends VariantProps<typeof PLAN_SELECTOR_STYLES> {
|
||||||
readonly showFreePlan?: boolean
|
readonly showFreePlan?: boolean
|
||||||
readonly hasTrial?: boolean
|
readonly hasTrial?: boolean
|
||||||
readonly userPlan?: Plan | undefined
|
readonly userPlan?: Plan | undefined
|
||||||
@ -36,6 +38,26 @@ export interface PlanSelectorProps {
|
|||||||
readonly onSubscribeError?: (error: Error) => void
|
readonly onSubscribeError?: (error: Error) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PLAN_SELECTOR_STYLES = tv({
|
||||||
|
base: DIALOG_BACKGROUND({
|
||||||
|
className: 'w-full snap-x overflow-auto rounded-4xl scroll-hidden',
|
||||||
|
}),
|
||||||
|
variants: {
|
||||||
|
showFreePlan: {
|
||||||
|
true: {
|
||||||
|
grid: 'grid-cols-1fr md:grid-cols-2 xl:grid-cols-4',
|
||||||
|
},
|
||||||
|
false: {
|
||||||
|
grid: 'grid-cols-1fr md:grid-cols-3 justify-center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
slots: {
|
||||||
|
grid: 'inline-grid min-w-full gap-6 p-6',
|
||||||
|
card: 'min-w-64 snap-center',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plan selector component.
|
* Plan selector component.
|
||||||
* Shows the available plans and allows the user to subscribe to one.
|
* Shows the available plans and allows the user to subscribe to one.
|
||||||
@ -49,6 +71,7 @@ export function PlanSelector(props: PlanSelectorProps) {
|
|||||||
showFreePlan = true,
|
showFreePlan = true,
|
||||||
hasTrial = true,
|
hasTrial = true,
|
||||||
isOrganizationAdmin = false,
|
isOrganizationAdmin = false,
|
||||||
|
variants = PLAN_SELECTOR_STYLES,
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const { getText } = useText()
|
const { getText } = useText()
|
||||||
@ -77,13 +100,11 @@ export function PlanSelector(props: PlanSelectorProps) {
|
|||||||
onError: (error) => onSubscribeError?.(error),
|
onError: (error) => onSubscribeError?.(error),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const classes = variants({ showFreePlan })
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={classes.base()}>
|
||||||
className={DIALOG_BACKGROUND({
|
<div className={classes.grid()}>
|
||||||
className: 'w-full snap-x overflow-auto rounded-4xl scroll-hidden',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div className="inline-grid min-w-full grid-cols-1fr gap-6 p-6 md:grid-cols-2 xl:grid-cols-4">
|
|
||||||
{PLANS.map((newPlan) => {
|
{PLANS.map((newPlan) => {
|
||||||
const paywallLevel = getPaywallLevel(newPlan)
|
const paywallLevel = getPaywallLevel(newPlan)
|
||||||
const userPaywallLevel = getPaywallLevel(userPlan)
|
const userPaywallLevel = getPaywallLevel(userPlan)
|
||||||
@ -96,7 +117,7 @@ export function PlanSelector(props: PlanSelectorProps) {
|
|||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
key={newPlan}
|
key={newPlan}
|
||||||
className="min-w-64 snap-center"
|
className={classes.card()}
|
||||||
features={planProps.features}
|
features={planProps.features}
|
||||||
subtitle={planProps.subtitle}
|
subtitle={planProps.subtitle}
|
||||||
title={planProps.title}
|
title={planProps.title}
|
||||||
@ -112,6 +133,7 @@ export function PlanSelector(props: PlanSelectorProps) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const startEpochMs = Number(new Date())
|
const startEpochMs = Number(new Date())
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const { data: session } = await refetchSession()
|
const { data: session } = await refetchSession()
|
||||||
if (session && 'user' in session && session.user.plan === newPlan) {
|
if (session && 'user' in session && session.user.plan === newPlan) {
|
||||||
|
@ -68,6 +68,7 @@ const BASE_STEPS: Step[] = [
|
|||||||
const userSession = useUserSession()
|
const userSession = useUserSession()
|
||||||
const { getText } = textProvider.useText()
|
const { getText } = textProvider.useText()
|
||||||
|
|
||||||
|
const isUserCreated = userSession?.type === UserSessionType.full
|
||||||
const defaultName =
|
const defaultName =
|
||||||
session && 'user' in session ? session.user.name : userSession?.email ?? ''
|
session && 'user' in session ? session.user.name : userSession?.email ?? ''
|
||||||
|
|
||||||
@ -85,7 +86,8 @@ const BASE_STEPS: Step[] = [
|
|||||||
}
|
}
|
||||||
defaultValues={{ username: defaultName }}
|
defaultValues={{ username: defaultName }}
|
||||||
onSubmit={({ username }) => {
|
onSubmit={({ username }) => {
|
||||||
if (username === defaultName) {
|
// If user is already created we shouldn't call `setUsername` if value wasn't changed
|
||||||
|
if (username === defaultName && isUserCreated) {
|
||||||
goToNextStep()
|
goToNextStep()
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user