diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql index d0a8d32195..7c7f1ee5f6 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -3315,7 +3315,7 @@ type Mutation { deleteEmailingDomain(id: String!): Boolean! verifyEmailingDomain(id: String!): EmailingDomain! createOneAppToken(input: CreateOneAppTokenInput!): AppToken! - installMarketplaceApp(universalIdentifier: String!, version: String): Boolean! + installMarketplaceApp(universalIdentifier: String!, version: String): Application! syncMarketplaceCatalog: Boolean! createDevelopmentApplication(universalIdentifier: String!, name: String!): DevelopmentApplication! generateApplicationToken(applicationId: UUID!): ApplicationTokenPair! diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts index 7e0025ea0e..28dd022709 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -2848,7 +2848,7 @@ export interface Mutation { deleteEmailingDomain: Scalars['Boolean'] verifyEmailingDomain: EmailingDomain createOneAppToken: AppToken - installMarketplaceApp: Scalars['Boolean'] + installMarketplaceApp: Application syncMarketplaceCatalog: Scalars['Boolean'] createDevelopmentApplication: DevelopmentApplication generateApplicationToken: ApplicationTokenPair @@ -5900,7 +5900,7 @@ export interface MutationGenqlSelection{ deleteEmailingDomain?: { __args: {id: Scalars['String']} } verifyEmailingDomain?: (EmailingDomainGenqlSelection & { __args: {id: Scalars['String']} }) createOneAppToken?: (AppTokenGenqlSelection & { __args: {input: CreateOneAppTokenInput} }) - installMarketplaceApp?: { __args: {universalIdentifier: Scalars['String'], version?: (Scalars['String'] | null)} } + installMarketplaceApp?: (ApplicationGenqlSelection & { __args: {universalIdentifier: Scalars['String'], version?: (Scalars['String'] | null)} }) syncMarketplaceCatalog?: boolean | number createDevelopmentApplication?: (DevelopmentApplicationGenqlSelection & { __args: {universalIdentifier: Scalars['String'], name: Scalars['String']} }) generateApplicationToken?: (ApplicationTokenPairGenqlSelection & { __args: {applicationId: Scalars['UUID']} }) diff --git a/packages/twenty-client-sdk/src/metadata/generated/types.ts b/packages/twenty-client-sdk/src/metadata/generated/types.ts index b426d01484..deff746236 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/types.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/types.ts @@ -8602,7 +8602,7 @@ export default { } ], "installMarketplaceApp": [ - 6, + 58, { "universalIdentifier": [ 1, diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 0108c8e7dd..a70107c8ad 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -2458,7 +2458,7 @@ export type Mutation = { initiateOTPProvisioning: InitiateTwoFactorAuthenticationProvisioning; initiateOTPProvisioningForAuthenticatedUser: InitiateTwoFactorAuthenticationProvisioning; installApplication: Scalars['Boolean']; - installMarketplaceApp: Scalars['Boolean']; + installMarketplaceApp: Application; refreshEnterpriseValidityToken: Scalars['Boolean']; removeQueryFromEventStream: Scalars['Boolean']; removeRoleFromAgent: Scalars['Boolean']; @@ -6626,7 +6626,7 @@ export type InstallMarketplaceAppMutationVariables = Exact<{ }>; -export type InstallMarketplaceAppMutation = { __typename?: 'Mutation', installMarketplaceApp: boolean }; +export type InstallMarketplaceAppMutation = { __typename?: 'Mutation', installMarketplaceApp: { __typename?: 'Application', id: string } }; export type UpgradeApplicationMutationVariables = Exact<{ appRegistrationId: Scalars['String']; @@ -8014,7 +8014,7 @@ export const FindManyAvailablePackagesDocument = {"kind":"Document","definitions export const FindManyLogicFunctionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindManyLogicFunctions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findManyLogicFunctions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LogicFunctionFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LogicFunctionFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LogicFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"timeoutSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"sourceHandlerPath"}},{"kind":"Field","name":{"kind":"Name","value":"handlerName"}},{"kind":"Field","name":{"kind":"Name","value":"cronTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"databaseEventTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"httpRouteTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"toolTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"workflowActionTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode; export const FindOneLogicFunctionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindOneLogicFunction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"LogicFunctionIdInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findOneLogicFunction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LogicFunctionFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LogicFunctionFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LogicFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"timeoutSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"sourceHandlerPath"}},{"kind":"Field","name":{"kind":"Name","value":"handlerName"}},{"kind":"Field","name":{"kind":"Name","value":"cronTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"databaseEventTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"httpRouteTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"toolTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"workflowActionTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode; export const GetLogicFunctionSourceCodeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetLogicFunctionSourceCode"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"LogicFunctionIdInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getLogicFunctionSourceCode"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; -export const InstallMarketplaceAppDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InstallMarketplaceApp"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"version"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"installMarketplaceApp"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"universalIdentifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}}},{"kind":"Argument","name":{"kind":"Name","value":"version"},"value":{"kind":"Variable","name":{"kind":"Name","value":"version"}}}]}]}}]} as unknown as DocumentNode; +export const InstallMarketplaceAppDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InstallMarketplaceApp"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"version"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"installMarketplaceApp"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"universalIdentifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}}},{"kind":"Argument","name":{"kind":"Name","value":"version"},"value":{"kind":"Variable","name":{"kind":"Name","value":"version"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const UpgradeApplicationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpgradeApplication"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appRegistrationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetVersion"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upgradeApplication"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appRegistrationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appRegistrationId"}}},{"kind":"Argument","name":{"kind":"Name","value":"targetVersion"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetVersion"}}}]}]}}]} as unknown as DocumentNode; export const FindManyMarketplaceAppsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindManyMarketplaceApps"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findManyMarketplaceApps"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"MarketplaceAppFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"MarketplaceAppFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"MarketplaceApp"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"author"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"sourcePackage"}},{"kind":"Field","name":{"kind":"Name","value":"isFeatured"}}]}}]} as unknown as DocumentNode; export const FindMarketplaceAppDetailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindMarketplaceAppDetail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findMarketplaceAppDetail"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"universalIdentifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"MarketplaceAppDetailFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"MarketplaceAppDetailFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"MarketplaceAppDetail"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sourceType"}},{"kind":"Field","name":{"kind":"Name","value":"sourcePackage"}},{"kind":"Field","name":{"kind":"Name","value":"latestAvailableVersion"}},{"kind":"Field","name":{"kind":"Name","value":"isListed"}},{"kind":"Field","name":{"kind":"Name","value":"isFeatured"}},{"kind":"Field","name":{"kind":"Name","value":"manifest"}}]}}]} as unknown as DocumentNode; diff --git a/packages/twenty-front/src/modules/marketplace/graphql/mutations/installMarketplaceApp.ts b/packages/twenty-front/src/modules/marketplace/graphql/mutations/installMarketplaceApp.ts index aba1aaf25b..af96c428a6 100644 --- a/packages/twenty-front/src/modules/marketplace/graphql/mutations/installMarketplaceApp.ts +++ b/packages/twenty-front/src/modules/marketplace/graphql/mutations/installMarketplaceApp.ts @@ -8,6 +8,8 @@ export const INSTALL_MARKETPLACE_APP = gql` installMarketplaceApp( universalIdentifier: $universalIdentifier version: $version - ) + ) { + id + } } `; diff --git a/packages/twenty-front/src/modules/marketplace/hooks/useInstallApp.ts b/packages/twenty-front/src/modules/marketplace/hooks/useInstallApp.ts deleted file mode 100644 index 211c90e034..0000000000 --- a/packages/twenty-front/src/modules/marketplace/hooks/useInstallApp.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { t } from '@lingui/core/macro'; -import { useState } from 'react'; -import { isDefined } from 'twenty-shared/utils'; - -export const useInstallApp = >( - mutationFn: (options: { - variables: TVariables; - }) => Promise<{ data?: Record | null }>, -) => { - const { enqueueErrorSnackBar, enqueueSuccessSnackBar } = useSnackBar(); - const [isInstalling, setIsInstalling] = useState(false); - - const install = async (variables: TVariables) => { - setIsInstalling(true); - - try { - const result = await mutationFn({ variables }); - - if (isDefined(result.data)) { - enqueueSuccessSnackBar({ - message: t`Application installed successfully.`, - }); - - return true; - } - - return false; - } catch (error) { - const graphqlMessage = error instanceof Error ? error.message : undefined; - - enqueueErrorSnackBar({ - message: graphqlMessage ?? t`Failed to install the application.`, - }); - - return false; - } finally { - setIsInstalling(false); - } - }; - - return { install, isInstalling }; -}; diff --git a/packages/twenty-front/src/modules/marketplace/hooks/useInstallMarketplaceApp.ts b/packages/twenty-front/src/modules/marketplace/hooks/useInstallMarketplaceApp.ts index 6627667f2d..d24d9e7130 100644 --- a/packages/twenty-front/src/modules/marketplace/hooks/useInstallMarketplaceApp.ts +++ b/packages/twenty-front/src/modules/marketplace/hooks/useInstallMarketplaceApp.ts @@ -1,14 +1,50 @@ -import { useInstallApp } from '~/modules/marketplace/hooks/useInstallApp'; +import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { useMutation } from '@apollo/client/react'; -import { InstallMarketplaceAppDocument } from '~/generated-metadata/graphql'; +import { t } from '@lingui/core/macro'; +import { useState } from 'react'; +import { isDefined } from 'twenty-shared/utils'; +import { + InstallMarketplaceAppDocument, + type InstallMarketplaceAppMutation, +} from '~/generated-metadata/graphql'; export const useInstallMarketplaceApp = () => { + const { enqueueErrorSnackBar, enqueueSuccessSnackBar } = useSnackBar(); + const [isInstalling, setIsInstalling] = useState(false); const [installMarketplaceAppMutation] = useMutation( InstallMarketplaceAppDocument, ); - return useInstallApp<{ + const install = async (variables: { universalIdentifier: string; version?: string; - }>(installMarketplaceAppMutation); + }): Promise => { + setIsInstalling(true); + + try { + const result = await installMarketplaceAppMutation({ variables }); + + if (isDefined(result.data)) { + enqueueSuccessSnackBar({ + message: t`Application installed successfully.`, + }); + + return result.data; + } + + return null; + } catch (error) { + const graphqlMessage = error instanceof Error ? error.message : undefined; + + enqueueErrorSnackBar({ + message: graphqlMessage ?? t`Failed to install the application.`, + }); + + return null; + } finally { + setIsInstalling(false); + } + }; + + return { install, isInstalling }; }; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx index e975d95dfd..aa198c8538 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx @@ -10,6 +10,7 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use import { useQuery } from '@apollo/client/react'; import { t } from '@lingui/core/macro'; import { useParams } from 'react-router-dom'; +import { useNavigateSettings } from '~/hooks/useNavigateSettings'; import { type Manifest } from 'twenty-shared/application'; import { SettingsPath } from 'twenty-shared/types'; import { getSettingsPath, isDefined } from 'twenty-shared/utils'; @@ -43,6 +44,7 @@ export const SettingsAvailableApplicationDetails = () => { availableApplicationId: string; }>(); + const navigateSettings = useNavigateSettings(); const { install, isInstalling } = useInstallMarketplaceApp(); const { upgrade, isUpgrading } = useUpgradeApplication(); @@ -98,9 +100,17 @@ export const SettingsAvailableApplicationDetails = () => { const handleInstall = async () => { if (isDefined(detail)) { - await install({ + const data = await install({ universalIdentifier: detail.universalIdentifier, }); + + const applicationId = data?.installMarketplaceApp?.id; + + if (isDefined(applicationId)) { + navigateSettings(SettingsPath.ApplicationDetail, { + applicationId, + }); + } } }; diff --git a/packages/twenty-sdk/src/cli/utilities/api/file-api.ts b/packages/twenty-sdk/src/cli/utilities/api/file-api.ts index a2d069c86b..772f23acb3 100644 --- a/packages/twenty-sdk/src/cli/utilities/api/file-api.ts +++ b/packages/twenty-sdk/src/cli/utilities/api/file-api.ts @@ -140,7 +140,9 @@ export class FileApi { try { const mutation = ` mutation InstallMarketplaceApp($universalIdentifier: String!) { - installMarketplaceApp(universalIdentifier: $universalIdentifier) + installMarketplaceApp(universalIdentifier: $universalIdentifier) { + id + } } `; diff --git a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.module.ts b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.module.ts index 080a307d36..9b1b03d9d0 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.module.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.module.ts @@ -1,5 +1,6 @@ import { Module } from '@nestjs/common'; +import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { ApplicationRegistrationModule } from 'src/engine/core-modules/application/application-registration/application-registration.module'; import { ApplicationInstallModule } from 'src/engine/core-modules/application/application-install/application-install.module'; import { MarketplaceCatalogSyncCronCommand } from 'src/engine/core-modules/application/application-marketplace/crons/commands/marketplace-catalog-sync.cron.command'; @@ -15,6 +16,7 @@ import { MarketplaceCatalogSyncCommand } from 'src/engine/core-modules/applicati @Module({ imports: [ + ApplicationModule, ApplicationRegistrationModule, ApplicationInstallModule, FeatureFlagModule, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts index e10e2f2fce..a0b121a9b5 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts @@ -5,6 +5,8 @@ import { PermissionFlagType } from 'twenty-shared/constants'; import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; import { ApplicationRegistrationExceptionFilter } from 'src/engine/core-modules/application/application-registration/application-registration-exception-filter'; import { ApplicationInstallService } from 'src/engine/core-modules/application/application-install/application-install.service'; +import { ApplicationService } from 'src/engine/core-modules/application/application.service'; +import { ApplicationDTO } from 'src/engine/core-modules/application/dtos/application.dto'; import { MarketplaceAppDTO } from 'src/engine/core-modules/application/application-marketplace/dtos/marketplace-app.dto'; import { MarketplaceAppDetailDTO } from 'src/engine/core-modules/application/application-marketplace/dtos/marketplace-app-detail.dto'; import { MarketplaceQueryService } from 'src/engine/core-modules/application/application-marketplace/marketplace-query.service'; @@ -27,6 +29,7 @@ export class MarketplaceResolver { constructor( private readonly marketplaceQueryService: MarketplaceQueryService, private readonly applicationInstallService: ApplicationInstallService, + private readonly applicationService: ApplicationService, @InjectMessageQueue(MessageQueue.cronQueue) private readonly messageQueueService: MessageQueueService, ) {} @@ -45,24 +48,29 @@ export class MarketplaceResolver { ); } - @Mutation(() => Boolean) + @Mutation(() => ApplicationDTO) @UseGuards(SettingsPermissionGuard(PermissionFlagType.MARKETPLACE_APPS)) async installMarketplaceApp( @Args('universalIdentifier') universalIdentifier: string, @Args('version', { type: () => String, nullable: true }) version: string | undefined, @AuthWorkspace() workspace: WorkspaceEntity, - ): Promise { + ) { const registration = await this.marketplaceQueryService.findRegistrationByUniversalIdentifier( universalIdentifier, ); - return this.applicationInstallService.installApplication({ + await this.applicationInstallService.installApplication({ appRegistrationId: registration.id, version, workspaceId: workspace.id, }); + + return this.applicationService.findOneApplicationOrThrow({ + universalIdentifier, + workspaceId: workspace.id, + }); } @Mutation(() => Boolean) diff --git a/packages/twenty-server/test/integration/metadata/suites/application/marketplace-catalog-sync.integration-spec.ts b/packages/twenty-server/test/integration/metadata/suites/application/marketplace-catalog-sync.integration-spec.ts index fdc7c2f5c5..dba4588128 100644 --- a/packages/twenty-server/test/integration/metadata/suites/application/marketplace-catalog-sync.integration-spec.ts +++ b/packages/twenty-server/test/integration/metadata/suites/application/marketplace-catalog-sync.integration-spec.ts @@ -22,7 +22,9 @@ const MARKETPLACE_QUERY = ` const INSTALL_MUTATION = ` mutation InstallMarketplaceApp($universalIdentifier: String!) { - installMarketplaceApp(universalIdentifier: $universalIdentifier) + installMarketplaceApp(universalIdentifier: $universalIdentifier) { + id + } } `;