diff --git a/frontend/src/layout/GlobalModals.tsx b/frontend/src/layout/GlobalModals.tsx index 6340f68af9823..7ef5f0d546afb 100644 --- a/frontend/src/layout/GlobalModals.tsx +++ b/frontend/src/layout/GlobalModals.tsx @@ -2,6 +2,7 @@ import { LemonModal } from '@posthog/lemon-ui' import { actions, kea, path, reducers, useActions, useValues } from 'kea' import { FlaggedFeature } from 'lib/components/FlaggedFeature' import { HedgehogBuddyWithLogic } from 'lib/components/HedgehogBuddy/HedgehogBuddyWithLogic' +import { UpgradeModal } from 'lib/components/UpgradeModal/UpgradeModal' import { Prompt } from 'lib/logic/newPrompt/Prompt' import { Setup2FA } from 'scenes/authentication/Setup2FA' import { CreateOrganizationModal } from 'scenes/organization/CreateOrganizationModal' @@ -9,7 +10,6 @@ import { membersLogic } from 'scenes/organization/membersLogic' import { CreateProjectModal } from 'scenes/project/CreateProjectModal' import { inviteLogic } from 'scenes/settings/organization/inviteLogic' import { InviteModal } from 'scenes/settings/organization/InviteModal' -import { UpgradeModal } from 'scenes/UpgradeModal' import { userLogic } from 'scenes/userLogic' import type { globalModalsLogicType } from './GlobalModalsType' diff --git a/frontend/src/layout/navigation/OrganizationSwitcher.tsx b/frontend/src/layout/navigation/OrganizationSwitcher.tsx index 850f8642669c2..692d0c8846ad1 100644 --- a/frontend/src/layout/navigation/OrganizationSwitcher.tsx +++ b/frontend/src/layout/navigation/OrganizationSwitcher.tsx @@ -1,5 +1,6 @@ import { IconPlus } from '@posthog/icons' import { useActions, useValues } from 'kea' +import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic' import { LemonButton } from 'lib/lemon-ui/LemonButton' import { LemonDivider } from 'lib/lemon-ui/LemonDivider' import { LemonTag } from 'lib/lemon-ui/LemonTag/LemonTag' @@ -7,7 +8,6 @@ import { Lettermark } from 'lib/lemon-ui/Lettermark' import { membershipLevelToName } from 'lib/utils/permissioning' import { organizationLogic } from 'scenes/organizationLogic' import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' -import { sceneLogic } from 'scenes/sceneLogic' import { userLogic } from 'scenes/userLogic' import { AvailableFeature, OrganizationBasicType } from '~/types' @@ -48,7 +48,7 @@ export function OtherOrganizationButton({ export function NewOrganizationButton(): JSX.Element { const { closeAccountPopover } = useActions(navigationLogic) const { showCreateOrganizationModal } = useActions(globalModalsLogic) - const { guardAvailableFeature } = useActions(sceneLogic) + const { guardAvailableFeature } = useValues(upgradeModalLogic) return ( void }): JSX.Element { const { currentOrganization, projectCreationForbiddenReason } = useValues(organizationLogic) const { currentTeam } = useValues(teamLogic) - const { guardAvailableFeature } = useActions(sceneLogic) + const { guardAvailableFeature } = useValues(upgradeModalLogic) const { showCreateProjectModal } = useActions(globalModalsLogic) return ( @@ -49,12 +49,9 @@ export function ProjectSwitcherOverlay({ onClickInside }: { onClickInside?: () = data-attr="new-project-button" onClick={() => { onClickInside?.() - guardAvailableFeature( - AvailableFeature.ORGANIZATIONS_PROJECTS, - showCreateProjectModal, - undefined, - currentOrganization?.teams?.length - ) + guardAvailableFeature(AvailableFeature.ORGANIZATIONS_PROJECTS, showCreateProjectModal, { + currentUsage: currentOrganization?.teams?.length, + }) }} > New project diff --git a/frontend/src/lib/components/ObjectTags/ObjectTags.tsx b/frontend/src/lib/components/ObjectTags/ObjectTags.tsx index aa4ca58253c96..b58b4a2caa33e 100644 --- a/frontend/src/lib/components/ObjectTags/ObjectTags.tsx +++ b/frontend/src/lib/components/ObjectTags/ObjectTags.tsx @@ -9,11 +9,11 @@ import { objectTagsLogic } from 'lib/components/ObjectTags/objectTagsLogic' import { Spinner } from 'lib/lemon-ui/Spinner/Spinner' import { colorForString } from 'lib/utils' import { CSSProperties, useMemo } from 'react' -import { sceneLogic } from 'scenes/sceneLogic' import { AvailableFeature } from '~/types' import { SelectGradientOverflow } from '../SelectGradientOverflow' +import { upgradeModalLogic } from '../UpgradeModal/upgradeModalLogic' interface ObjectTagsPropsBase { tags: string[] @@ -61,7 +61,7 @@ export function ObjectTags({ }: ObjectTagsProps): JSX.Element { const objectTagId = useMemo(() => uniqueMemoizedIndex++, []) const logic = objectTagsLogic({ id: objectTagId, onChange, tags }) - const { guardAvailableFeature } = useActions(sceneLogic) + const { guardAvailableFeature } = useValues(upgradeModalLogic) const { addingNewTag, cleanedNewTag, deletedTags } = useValues(logic) const { setAddingNewTag, setNewTag, handleDelete, handleAdd } = useActions(logic) diff --git a/frontend/src/lib/components/PayGateMini/PayGateMini.tsx b/frontend/src/lib/components/PayGateMini/PayGateMini.tsx index 38acd75ace822..5ea5ec55e8d0a 100644 --- a/frontend/src/lib/components/PayGateMini/PayGateMini.tsx +++ b/frontend/src/lib/components/PayGateMini/PayGateMini.tsx @@ -10,10 +10,10 @@ import { useEffect } from 'react' import { billingLogic } from 'scenes/billing/billingLogic' import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' import { getProductIcon } from 'scenes/products/Products' -import { sceneLogic } from 'scenes/sceneLogic' import { AvailableFeature } from '~/types' +import { upgradeModalLogic } from '../UpgradeModal/upgradeModalLogic' import { PayGateMiniButton } from './PayGateMiniButton' import { payGateMiniLogic } from './payGateMiniLogic' @@ -47,7 +47,7 @@ export function PayGateMini({ const { preflight } = useValues(preflightLogic) const { billing, billingLoading } = useValues(billingLogic) const { featureFlags } = useValues(featureFlagLogic) - const { hideUpgradeModal } = useActions(sceneLogic) + const { hideUpgradeModal } = useActions(upgradeModalLogic) useEffect(() => { if (gateVariant) { diff --git a/frontend/src/lib/components/Sharing/SharingModal.tsx b/frontend/src/lib/components/Sharing/SharingModal.tsx index 410af5493ef16..8db90e2bca2f2 100644 --- a/frontend/src/lib/components/Sharing/SharingModal.tsx +++ b/frontend/src/lib/components/Sharing/SharingModal.tsx @@ -15,10 +15,10 @@ import { Tooltip } from 'lib/lemon-ui/Tooltip' import { copyToClipboard } from 'lib/utils/copyToClipboard' import { useEffect, useState } from 'react' import { DashboardCollaboration } from 'scenes/dashboard/DashboardCollaborators' -import { sceneLogic } from 'scenes/sceneLogic' import { AvailableFeature, InsightModel, InsightShortId, InsightType } from '~/types' +import { upgradeModalLogic } from '../UpgradeModal/upgradeModalLogic' import { sharingLogic } from './sharingLogic' export const SHARING_MODAL_WIDTH = 600 @@ -64,7 +64,7 @@ export function SharingModalContent({ shareLink, } = useValues(sharingLogic(logicProps)) const { setIsEnabled, togglePreview } = useActions(sharingLogic(logicProps)) - const { guardAvailableFeature } = useActions(sceneLogic) + const { guardAvailableFeature } = useValues(upgradeModalLogic) const [iframeLoaded, setIframeLoaded] = useState(false) diff --git a/frontend/src/scenes/UpgradeModal.tsx b/frontend/src/lib/components/UpgradeModal/UpgradeModal.tsx similarity index 85% rename from frontend/src/scenes/UpgradeModal.tsx rename to frontend/src/lib/components/UpgradeModal/UpgradeModal.tsx index bea905c356b1d..d731a6774772b 100644 --- a/frontend/src/scenes/UpgradeModal.tsx +++ b/frontend/src/lib/components/UpgradeModal/UpgradeModal.tsx @@ -2,11 +2,12 @@ import { LemonModal } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { PayGateMini } from 'lib/components/PayGateMini/PayGateMini' -import { sceneLogic } from './sceneLogic' +import { upgradeModalLogic } from './upgradeModalLogic' export function UpgradeModal(): JSX.Element { - const { upgradeModalFeatureKey, upgradeModalFeatureUsage, upgradeModalIsGrandfathered } = useValues(sceneLogic) - const { hideUpgradeModal } = useActions(sceneLogic) + const { upgradeModalFeatureKey, upgradeModalFeatureUsage, upgradeModalIsGrandfathered } = + useValues(upgradeModalLogic) + const { hideUpgradeModal } = useActions(upgradeModalLogic) return upgradeModalFeatureKey ? ( diff --git a/frontend/src/lib/components/UpgradeModal/upgradeModalLogic.ts b/frontend/src/lib/components/UpgradeModal/upgradeModalLogic.ts new file mode 100644 index 0000000000000..9542ac6a208dc --- /dev/null +++ b/frontend/src/lib/components/UpgradeModal/upgradeModalLogic.ts @@ -0,0 +1,96 @@ +import { actions, connect, kea, listeners, path, reducers, selectors } from 'kea' +import { featureFlagLogic } from 'lib/logic/featureFlagLogic' +import { eventUsageLogic } from 'lib/utils/eventUsageLogic' +import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic' +import { userLogic } from 'scenes/userLogic' + +import { AvailableFeature } from '~/types' + +import type { upgradeModalLogicType } from './upgradeModalLogicType' + +export type GuardAvailableFeatureFn = ( + featureKey: AvailableFeature, + featureAvailableCallback?: () => void, + options?: { + guardOnCloud?: boolean + guardOnSelfHosted?: boolean + currentUsage?: number + isGrandfathered?: boolean + } +) => boolean + +export const upgradeModalLogic = kea([ + path(['lib', 'components', 'UpgradeModal', 'upgradeModalLogic']), + connect(() => ({ + values: [preflightLogic, ['preflight'], featureFlagLogic, ['featureFlags'], userLogic, ['hasAvailableFeature']], + })), + actions({ + showUpgradeModal: (featureKey: AvailableFeature, currentUsage?: number, isGrandfathered?: boolean) => ({ + featureKey, + currentUsage, + isGrandfathered, + }), + hideUpgradeModal: true, + }), + reducers({ + upgradeModalFeatureKey: [ + null as AvailableFeature | null, + { + showUpgradeModal: (_, { featureKey }) => featureKey, + hideUpgradeModal: () => null, + }, + ], + upgradeModalFeatureUsage: [ + null as number | null, + { + showUpgradeModal: (_, { currentUsage }) => currentUsage ?? null, + hideUpgradeModal: () => null, + }, + ], + upgradeModalIsGrandfathered: [ + null as boolean | null, + { + showUpgradeModal: (_, { isGrandfathered }) => isGrandfathered ?? null, + hideUpgradeModal: () => null, + }, + ], + }), + selectors(({ actions }) => ({ + guardAvailableFeature: [ + (s) => [s.preflight, s.hasAvailableFeature], + (preflight, hasAvailableFeature): GuardAvailableFeatureFn => { + return (featureKey, featureAvailableCallback, options): boolean => { + const { + guardOnCloud = true, + guardOnSelfHosted = true, + currentUsage, + isGrandfathered, + } = options || {} + let featureAvailable: boolean + if (!preflight) { + featureAvailable = false + } else if (!guardOnCloud && preflight.cloud) { + featureAvailable = true + } else if (!guardOnSelfHosted && !preflight.cloud) { + featureAvailable = true + } else { + featureAvailable = hasAvailableFeature(featureKey, currentUsage) + } + + if (!featureAvailable) { + actions.showUpgradeModal(featureKey, currentUsage, isGrandfathered) + } else { + featureAvailableCallback?.() + } + + return featureAvailable + } + }, + ], + })), + listeners(() => ({ + showUpgradeModal: ({ featureKey }) => { + eventUsageLogic.actions.reportUpgradeModalShown(featureKey) + }, + })), +]) diff --git a/frontend/src/scenes/sceneLogic.ts b/frontend/src/scenes/sceneLogic.ts index bfb5fe46210da..998726e131ec5 100644 --- a/frontend/src/scenes/sceneLogic.ts +++ b/frontend/src/scenes/sceneLogic.ts @@ -4,14 +4,13 @@ import { commandBarLogic } from 'lib/components/CommandBar/commandBarLogic' import { BarStatus } from 'lib/components/CommandBar/types' import { FEATURE_FLAGS, TeamMembershipLevel } from 'lib/constants' import { featureFlagLogic } from 'lib/logic/featureFlagLogic' -import { eventUsageLogic } from 'lib/utils/eventUsageLogic' import { addProjectIdIfMissing, removeProjectIdIfPresent } from 'lib/utils/router-utils' import posthog from 'posthog-js' import { emptySceneParams, preloadedScenes, redirects, routes, sceneConfigurations } from 'scenes/scenes' import { LoadedScene, Params, Scene, SceneConfig, SceneExport, SceneParams } from 'scenes/sceneTypes' import { urls } from 'scenes/urls' -import { AvailableFeature, ProductKey } from '~/types' +import { ProductKey } from '~/types' import { handleLoginRedirect } from './authentication/loginLogic' import { onboardingLogic, OnboardingStepKey } from './onboarding/onboardingLogic' @@ -52,27 +51,6 @@ export const sceneLogic = kea([ setLoadedScene: (loadedScene: LoadedScene) => ({ loadedScene, }), - showUpgradeModal: (featureKey: AvailableFeature, currentUsage?: number, isGrandfathered?: boolean) => ({ - featureKey, - currentUsage, - isGrandfathered, - }), - guardAvailableFeature: ( - featureKey: AvailableFeature, - featureAvailableCallback?: () => void, - guardOn: { - cloud: boolean - selfHosted: boolean - } = { - cloud: true, - selfHosted: true, - }, - // how much of the feature has been used (eg. number of recording playlists created), - // which will be compared to the limit for their subscriptions - currentUsage?: number, - isGrandfathered?: boolean - ) => ({ featureKey, featureAvailableCallback, guardOn, currentUsage, isGrandfathered }), - hideUpgradeModal: true, reloadBrowserDueToImportError: true, }), reducers({ @@ -105,27 +83,6 @@ export const sceneLogic = kea([ setScene: () => null, }, ], - upgradeModalFeatureKey: [ - null as AvailableFeature | null, - { - showUpgradeModal: (_, { featureKey }) => featureKey, - hideUpgradeModal: () => null, - }, - ], - upgradeModalFeatureUsage: [ - null as number | null, - { - showUpgradeModal: (_, { currentUsage }) => currentUsage ?? null, - hideUpgradeModal: () => null, - }, - ], - upgradeModalIsGrandfathered: [ - null as boolean | null, - { - showUpgradeModal: (_, { isGrandfathered }) => isGrandfathered ?? null, - hideUpgradeModal: () => null, - }, - ], lastReloadAt: [ null as number | null, { persist: true }, @@ -170,27 +127,6 @@ export const sceneLogic = kea([ hashParams: [(s) => [s.sceneParams], (sceneParams): Record => sceneParams.hashParams || {}], }), listeners(({ values, actions, props, selectors }) => ({ - showUpgradeModal: ({ featureKey }) => { - eventUsageLogic.actions.reportUpgradeModalShown(featureKey) - }, - guardAvailableFeature: ({ featureKey, featureAvailableCallback, guardOn, currentUsage, isGrandfathered }) => { - const { preflight } = preflightLogic.values - let featureAvailable: boolean - if (!preflight) { - featureAvailable = false - } else if (!guardOn.cloud && preflight.cloud) { - featureAvailable = true - } else if (!guardOn.selfHosted && !preflight.cloud) { - featureAvailable = true - } else { - featureAvailable = userLogic.values.hasAvailableFeature(featureKey, currentUsage) - } - if (featureAvailable) { - featureAvailableCallback?.() - } else { - actions.showUpgradeModal(featureKey, currentUsage, isGrandfathered) - } - }, setScene: ({ scene, scrollToTop }, _, __, previousState) => { posthog.capture('$pageview') diff --git a/frontend/src/scenes/session-recordings/SessionRecordings.tsx b/frontend/src/scenes/session-recordings/SessionRecordings.tsx index ecf99b63e88b2..383a0f27a5073 100644 --- a/frontend/src/scenes/session-recordings/SessionRecordings.tsx +++ b/frontend/src/scenes/session-recordings/SessionRecordings.tsx @@ -4,6 +4,7 @@ import { useActions, useValues } from 'kea' import { router } from 'kea-router' import { authorizedUrlListLogic, AuthorizedUrlListType } from 'lib/components/AuthorizedUrlList/authorizedUrlListLogic' import { PageHeader } from 'lib/components/PageHeader' +import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic' import { VersionCheckerBanner } from 'lib/components/VersionChecker/VersionCheckerBanner' import { useAsyncHandler } from 'lib/hooks/useAsyncHandler' import { useFeatureFlag } from 'lib/hooks/useFeatureFlag' @@ -12,7 +13,6 @@ import { LemonTabs } from 'lib/lemon-ui/LemonTabs' import { Spinner } from 'lib/lemon-ui/Spinner/Spinner' import { eventUsageLogic } from 'lib/utils/eventUsageLogic' import { NotebookSelectButton } from 'scenes/notebooks/NotebookSelectButton/NotebookSelectButton' -import { sceneLogic } from 'scenes/sceneLogic' import { SceneExport } from 'scenes/sceneTypes' import { sessionRecordingsPlaylistLogic } from 'scenes/session-recordings/playlist/sessionRecordingsPlaylistLogic' import { teamLogic } from 'scenes/teamLogic' @@ -34,7 +34,7 @@ export function SessionsRecordings(): JSX.Element { const { tab } = useValues(sessionRecordingsLogic) const recordingsDisabled = currentTeam && !currentTeam?.session_recording_opt_in const { reportRecordingPlaylistCreated } = useActions(eventUsageLogic) - const { guardAvailableFeature } = useActions(sceneLogic) + const { guardAvailableFeature } = useValues(upgradeModalLogic) const playlistsLogic = savedSessionRecordingPlaylistsLogic({ tab: ReplayTabs.Recent }) const { playlists } = useValues(playlistsLogic) const { openSettingsPanel } = useActions(sidePanelSettingsLogic) @@ -87,8 +87,7 @@ export function SessionsRecordings(): JSX.Element { ? newPlaylistHandler.onEvent?.(e) : saveFiltersPlaylistHandler.onEvent?.(e) }, - undefined, - playlists.count + { currentUsage: playlists.count } ) } > @@ -111,8 +110,7 @@ export function SessionsRecordings(): JSX.Element { guardAvailableFeature( AvailableFeature.RECORDINGS_PLAYLISTS, () => newPlaylistHandler.onEvent?.(e), - undefined, - playlists.count + { currentUsage: playlists.count } ) } data-attr="save-recordings-playlist-button" diff --git a/frontend/src/scenes/session-recordings/saved-playlists/SavedSessionRecordingPlaylistsEmptyState.tsx b/frontend/src/scenes/session-recordings/saved-playlists/SavedSessionRecordingPlaylistsEmptyState.tsx index 7ef7ede4a778e..062b6c5ecf214 100644 --- a/frontend/src/scenes/session-recordings/saved-playlists/SavedSessionRecordingPlaylistsEmptyState.tsx +++ b/frontend/src/scenes/session-recordings/saved-playlists/SavedSessionRecordingPlaylistsEmptyState.tsx @@ -1,8 +1,8 @@ import { IconPlus } from '@posthog/icons' -import { useActions, useValues } from 'kea' +import { useValues } from 'kea' +import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic' import { LemonBanner } from 'lib/lemon-ui/LemonBanner' import { LemonButton } from 'lib/lemon-ui/LemonButton' -import { sceneLogic } from 'scenes/sceneLogic' import { AvailableFeature, ReplayTabs } from '~/types' @@ -10,7 +10,7 @@ import { createPlaylist } from '../playlist/playlistUtils' import { savedSessionRecordingPlaylistsLogic } from './savedSessionRecordingPlaylistsLogic' export function SavedSessionRecordingPlaylistsEmptyState(): JSX.Element { - const { guardAvailableFeature } = useActions(sceneLogic) + const { guardAvailableFeature } = useValues(upgradeModalLogic) const playlistsLogic = savedSessionRecordingPlaylistsLogic({ tab: ReplayTabs.Recent }) const { playlists, loadPlaylistsFailed } = useValues(playlistsLogic) return loadPlaylistsFailed ? ( @@ -28,8 +28,7 @@ export function SavedSessionRecordingPlaylistsEmptyState(): JSX.Element { guardAvailableFeature( AvailableFeature.RECORDINGS_PLAYLISTS, () => void createPlaylist({}, true), - undefined, - playlists.count + { currentUsage: playlists.count } ) } > diff --git a/frontend/src/scenes/settings/project/AddMembersModal.tsx b/frontend/src/scenes/settings/project/AddMembersModal.tsx index 1bd544eb04fdd..ea355fa6429e0 100644 --- a/frontend/src/scenes/settings/project/AddMembersModal.tsx +++ b/frontend/src/scenes/settings/project/AddMembersModal.tsx @@ -1,15 +1,15 @@ import { IconPlus } from '@posthog/icons' import { LemonButton, LemonModal, LemonSelect, LemonSelectOption } from '@posthog/lemon-ui' -import { useActions, useValues } from 'kea' +import { useValues } from 'kea' import { Form } from 'kea-forms' import { RestrictedComponentProps } from 'lib/components/RestrictedArea' +import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic' import { usersLemonSelectOptions } from 'lib/components/UserSelectItem' import { TeamMembershipLevel } from 'lib/constants' import { LemonField } from 'lib/lemon-ui/LemonField' import { LemonInputSelect } from 'lib/lemon-ui/LemonInputSelect/LemonInputSelect' import { membershipLevelToName, teamMembershipLevelIntegers } from 'lib/utils/permissioning' import { useState } from 'react' -import { sceneLogic } from 'scenes/sceneLogic' import { teamLogic } from 'scenes/teamLogic' import { userLogic } from 'scenes/userLogic' @@ -20,7 +20,7 @@ import { teamMembersLogic } from './teamMembersLogic' export function AddMembersModalWithButton({ isRestricted }: RestrictedComponentProps): JSX.Element { const { addableMembers, allMembersLoading } = useValues(teamMembersLogic) const { currentTeam } = useValues(teamLogic) - const { guardAvailableFeature } = useActions(sceneLogic) + const { guardAvailableFeature } = useValues(upgradeModalLogic) const { hasAvailableFeature } = useValues(userLogic) const [isVisible, setIsVisible] = useState(false) @@ -35,14 +35,11 @@ export function AddMembersModalWithButton({ isRestricted }: RestrictedComponentP type="primary" data-attr="add-project-members-button" onClick={() => - guardAvailableFeature( - AvailableFeature.PROJECT_BASED_PERMISSIONING, - () => setIsVisible(true), - undefined, - undefined, - !hasAvailableFeature(AvailableFeature.PROJECT_BASED_PERMISSIONING) && - currentTeam?.access_control - ) + guardAvailableFeature(AvailableFeature.PROJECT_BASED_PERMISSIONING, () => setIsVisible(true), { + isGrandfathered: + !hasAvailableFeature(AvailableFeature.PROJECT_BASED_PERMISSIONING) && + currentTeam?.access_control, + }) } icon={} disabled={isRestricted} diff --git a/frontend/src/scenes/settings/project/ProjectAccessControl.tsx b/frontend/src/scenes/settings/project/ProjectAccessControl.tsx index b250d8386ecc3..fbe81e1942624 100644 --- a/frontend/src/scenes/settings/project/ProjectAccessControl.tsx +++ b/frontend/src/scenes/settings/project/ProjectAccessControl.tsx @@ -2,6 +2,7 @@ import { IconCrown, IconLeave, IconLock, IconUnlock } from '@posthog/icons' import { LemonButton, LemonSelect, LemonSelectOption, LemonSnack, LemonSwitch, LemonTable } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { RestrictedArea, RestrictionScope, useRestrictedArea } from 'lib/components/RestrictedArea' +import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic' import { OrganizationMembershipLevel, TeamMembershipLevel } from 'lib/constants' import { IconCancel } from 'lib/lemon-ui/icons' import { LemonDialog } from 'lib/lemon-ui/LemonDialog' @@ -15,7 +16,6 @@ import { teamMembershipLevelIntegers, } from 'lib/utils/permissioning' import { organizationLogic } from 'scenes/organizationLogic' -import { sceneLogic } from 'scenes/sceneLogic' import { isAuthenticatedTeam, teamLogic } from 'scenes/teamLogic' import { userLogic } from 'scenes/userLogic' @@ -208,7 +208,7 @@ export function ProjectAccessControl(): JSX.Element { const { currentOrganization, currentOrganizationLoading } = useValues(organizationLogic) const { currentTeam, currentTeamLoading } = useValues(teamLogic) const { updateCurrentTeam } = useActions(teamLogic) - const { guardAvailableFeature } = useActions(sceneLogic) + const { guardAvailableFeature } = useValues(upgradeModalLogic) const isRestricted = !!useRestrictedArea({ minimumAccessLevel: OrganizationMembershipLevel.Admin, diff --git a/frontend/src/scenes/surveys/SurveyAppearance.tsx b/frontend/src/scenes/surveys/SurveyAppearance.tsx index bc55c6c4b797f..750b880f7d28c 100644 --- a/frontend/src/scenes/surveys/SurveyAppearance.tsx +++ b/frontend/src/scenes/surveys/SurveyAppearance.tsx @@ -1,10 +1,10 @@ import './SurveyAppearance.scss' import { LemonButton, LemonCheckbox, LemonInput, LemonSelect, Link } from '@posthog/lemon-ui' -import { useActions, useValues } from 'kea' +import { useValues } from 'kea' import { PayGateMini } from 'lib/components/PayGateMini/PayGateMini' +import { upgradeModalLogic } from 'lib/components/UpgradeModal/upgradeModalLogic' import React, { useEffect, useRef, useState } from 'react' -import { sceneLogic } from 'scenes/sceneLogic' import { AvailableFeature, @@ -138,7 +138,7 @@ export function SurveyAppearance({ export function Customization({ appearance, surveyQuestionItem, onAppearanceChange }: CustomizationProps): JSX.Element { const { surveysStylingAvailable } = useValues(surveysLogic) - const { guardAvailableFeature } = useActions(sceneLogic) + const { guardAvailableFeature } = useValues(upgradeModalLogic) return ( <>