Compare commits

...

3 Commits

Author SHA1 Message Date
oguzhankoral 50e58a4091 fix: upgrade cta 2026-03-06 11:13:05 +03:00
Oğuzhan Koral 05bfc40ad6 Merge branch 'main' into bjorn/cnx-2294-upsell-message-display-only-when-user-is-trying-to-create-a 2026-03-06 10:53:00 +03:00
Björn Steinhagen 69c87e8ed3 chore: upsell message 2026-02-12 21:28:37 +02:00
3 changed files with 36 additions and 131 deletions
-27
View File
@@ -32,33 +32,6 @@
</FormButton> </FormButton>
</div> </div>
</div> </div>
<div
v-if="
canCreateModelResult &&
!canCreateModelResult.project.permissions.canCreateModel.authorized
"
>
<CommonAlert title="Cannot create new models" color="info" hide-icon>
<template #description>
{{ canCreateModelResult.project.permissions.canCreateModel.message }}
<FormButton
v-if="workspaceSlug"
full-width
color="primary"
size="sm"
class="mt-2"
@click="
$openUrl(
`${account.accountInfo.serverInfo.url}/settings/workspaces/${workspaceSlug}/billing`
)
"
>
Explore Plans
</FormButton>
</template>
</CommonAlert>
</div>
<div class="relative grid grid-cols-1 gap-2"> <div class="relative grid grid-cols-1 gap-2">
<CommonLoadingBar v-if="loading" loading /> <CommonLoadingBar v-if="loading" loading />
+36 -60
View File
@@ -3,7 +3,6 @@
<div class="space-y-2 relative"> <div class="space-y-2 relative">
<div v-if="workspacesEnabled && workspaces" class="flex items-center space-x-2"> <div v-if="workspacesEnabled && workspaces" class="flex items-center space-x-2">
<div class="flex-grow min-w-0"> <div class="flex-grow min-w-0">
<!-- NO WORKSPACE YET -->
<div v-if="workspaces.length === 0"> <div v-if="workspaces.length === 0">
<FormButton <FormButton
full-width full-width
@@ -79,13 +78,7 @@
color="foundation" color="foundation"
/> />
<div class="flex justify-between items-center space-x-2"> <div class="flex justify-between items-center space-x-2">
<div <div v-if="canCreateProject" v-tippy="'Create new project'">
v-tippy="
canCreateProject
? 'Create new project'
: canCreateProjectPermissionCheck?.message
"
>
<FormButton <FormButton
color="outline" color="outline"
:disabled="!canCreateProject" :disabled="!canCreateProject"
@@ -95,6 +88,22 @@
<PlusIcon class="w-4 -mx-2" /> <PlusIcon class="w-4 -mx-2" />
</FormButton> </FormButton>
</div> </div>
<div
v-else
v-tippy="
canCreateProject
? 'Create new project'
: canCreateProjectPermissionCheck?.message
"
>
<FormButton
color="primary"
:class="`p-1.5 bg-foundation rounded text-foreground border`"
@click="upgradePlanButtonAction"
>
<ArrowUpCircleIcon class="w-4 -mx-2" />
</FormButton>
</div>
<CommonDialog <CommonDialog
v-model:open="showProjectCreateDialog" v-model:open="showProjectCreateDialog"
:title="`Create new project`" :title="`Create new project`"
@@ -139,28 +148,6 @@
</div> </div>
</div> </div>
</div> </div>
<div
v-if="
canCreateProjectPermissionCheck &&
!canCreateProjectPermissionCheck.authorized &&
showUpgradePlanButton
"
>
<CommonAlert color="info" hide-icon>
<template #description>
{{ canCreateProjectPermissionCheck.message }}
<FormButton
full-width
class="mt-2"
color="primary"
size="sm"
@click="upgradePlanButtonAction()"
>
Upgrade now
</FormButton>
</template>
</CommonAlert>
</div>
<WizardPersonalProjectsWarning v-if="isPersonalProjectsAsWorkspace" /> <WizardPersonalProjectsWarning v-if="isPersonalProjectsAsWorkspace" />
@@ -209,7 +196,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ChevronDownIcon, ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/outline' import { ChevronDownIcon, ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/outline'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { PlusIcon } from '@heroicons/vue/20/solid' import { PlusIcon, ArrowUpCircleIcon } from '@heroicons/vue/20/solid'
import type { DUIAccount } from '~/store/accounts' import type { DUIAccount } from '~/store/accounts'
import { useAccountStore } from '~/store/accounts' import { useAccountStore } from '~/store/accounts'
import { import {
@@ -500,35 +487,6 @@ const canCreateProjectPermissionCheck = computed(() => {
return null return null
}) })
const upgradePlanButtonAction = () => {
if (!canCreateProjectPermissionCheck.value) return
if (canCreateProjectPermissionCheck.value.code === 'WorkspaceNoEditorSeat') {
// open url to workspace/settings/users
$openUrl(
`${account.value.accountInfo.serverInfo.url}/settings/workspaces/${selectedWorkspace.value?.slug}/members`
)
return
}
if (canCreateProjectPermissionCheck.value.code === 'WorkspaceLimitsReached') {
// open url to workspace/billing
$openUrl(
`${account.value.accountInfo.serverInfo.url}/settings/workspaces/${selectedWorkspace.value?.slug}/billing`
)
return
}
}
const showUpgradePlanButton = computed(() => {
if (!canCreateProjectPermissionCheck.value) return false
if (
canCreateProjectPermissionCheck.value.code === 'WorkspaceNoEditorSeat' ||
canCreateProjectPermissionCheck.value.code === 'WorkspaceLimitsReached'
) {
return true
}
return false
})
const isCreatingProject = ref(false) const isCreatingProject = ref(false)
const showProjectCreateDialog = ref(false) const showProjectCreateDialog = ref(false)
@@ -617,6 +575,24 @@ const createNewPersonalProject = async (name: string) => {
isCreatingProject.value = false isCreatingProject.value = false
} }
const upgradePlanButtonAction = () => {
if (!canCreateProjectPermissionCheck.value) return
if (canCreateProjectPermissionCheck.value.code === 'WorkspaceNoEditorSeat') {
// open url to workspace/settings/users
$openUrl(
`${account.value.accountInfo.serverInfo.url}/settings/workspaces/${selectedWorkspace.value?.slug}/members`
)
return
}
if (canCreateProjectPermissionCheck.value.code === 'WorkspaceLimitsReached') {
// open url to workspace/billing
$openUrl(
`${account.value.accountInfo.serverInfo.url}/settings/workspaces/${selectedWorkspace.value?.slug}/billing`
)
return
}
}
const loadMore = () => { const loadMore = () => {
fetchMore({ fetchMore({
variables: { cursor: projectsResult.value?.activeUser?.projects.cursor }, variables: { cursor: projectsResult.value?.activeUser?.projects.cursor },
-44
View File
@@ -1355,12 +1355,6 @@ export type CreateVersionInput = {
totalChildrenCount?: InputMaybe<Scalars['Int']['input']>; totalChildrenCount?: InputMaybe<Scalars['Int']['input']>;
}; };
export type CreateWorkspaceResourceMetaInput = {
data: Scalars['JSON']['input'];
metaType: Scalars['String']['input'];
workspaceId: Scalars['String']['input'];
};
export enum Currency { export enum Currency {
Gbp = 'gbp', Gbp = 'gbp',
Usd = 'usd' Usd = 'usd'
@@ -4186,19 +4180,6 @@ export type ProjectPermissionChecksCanUseInviteArgs = {
type?: InputMaybe<InviteUseType>; type?: InputMaybe<InviteUseType>;
}; };
export type ProjectResourceMeta = {
__typename?: 'ProjectResourceMeta';
authorId?: Maybe<Scalars['ID']['output']>;
createdAt: Scalars['DateTime']['output'];
data: Scalars['JSON']['output'];
id: Scalars['ID']['output'];
metaType: Scalars['String']['output'];
projectId: Scalars['String']['output'];
resourceId: Scalars['String']['output'];
resourceType: ResourceMetaType;
updatedAt: Scalars['DateTime']['output'];
};
export type ProjectRole = { export type ProjectRole = {
__typename?: 'ProjectRole'; __typename?: 'ProjectRole';
project: Project; project: Project;
@@ -4459,8 +4440,6 @@ export type Query = {
* Either token or workspaceId must be specified, or both * Either token or workspaceId must be specified, or both
*/ */
workspaceInvite?: Maybe<PendingWorkspaceCollaborator>; workspaceInvite?: Maybe<PendingWorkspaceCollaborator>;
workspaceResourceMeta: WorkspaceResourceMeta;
workspaceResourceMetaSearch: Array<WorkspaceResourceMeta>;
/** Find workspaces a given user email can use SSO to sign with */ /** Find workspaces a given user email can use SSO to sign with */
workspaceSsoByEmail: Array<LimitedWorkspace>; workspaceSsoByEmail: Array<LimitedWorkspace>;
}; };
@@ -4621,18 +4600,6 @@ export type QueryWorkspaceInviteArgs = {
}; };
export type QueryWorkspaceResourceMetaArgs = {
id: Scalars['ID']['input'];
workspaceId: Scalars['String']['input'];
};
export type QueryWorkspaceResourceMetaSearchArgs = {
metaType?: InputMaybe<Scalars['String']['input']>;
workspaceId: Scalars['String']['input'];
};
export type QueryWorkspaceSsoByEmailArgs = { export type QueryWorkspaceSsoByEmailArgs = {
email: Scalars['String']['input']; email: Scalars['String']['input'];
}; };
@@ -7392,17 +7359,6 @@ export type WorkspaceRequestToJoinInput = {
workspaceId: Scalars['ID']['input']; workspaceId: Scalars['ID']['input'];
}; };
export type WorkspaceResourceMeta = {
__typename?: 'WorkspaceResourceMeta';
authorId?: Maybe<Scalars['ID']['output']>;
createdAt: Scalars['DateTime']['output'];
data: Scalars['JSON']['output'];
id: Scalars['ID']['output'];
metaType: Scalars['String']['output'];
updatedAt: Scalars['DateTime']['output'];
workspaceId: Scalars['String']['output'];
};
export enum WorkspaceRole { export enum WorkspaceRole {
Admin = 'ADMIN', Admin = 'ADMIN',
Guest = 'GUEST', Guest = 'GUEST',