Add marketplace catalog synchronization to admin panel (#22260)
## After <img width="1476" height="658" alt="image" src="https://github.com/user-attachments/assets/25a042dd-eabf-4b71-9872-d3b627104634" /> ## Summary This PR adds the ability for admins to manually synchronize the marketplace application catalog from the admin panel. It introduces a new mutation endpoint and UI controls to trigger catalog synchronization with user feedback via snackbar notifications. ## Key Changes - **Frontend (SettingsAdminApps component)**: - Added `useSnackBar` hook for user feedback on sync success/failure - Imported `useMutation` from Apollo Client to handle the sync operation - Added `IconRefresh` and `Button` imports for the sync UI control - Created `handleSyncCatalog` function that triggers the mutation, refetches app registrations, and displays appropriate snackbar messages - Added a new "General" section with a "Synchronize catalog" button above the existing app registrations table - Button shows loading state and is disabled while sync is in progress - **Backend (AdminPanelResolver)**: - Added `syncMarketplaceCatalog` mutation that queues a `MarketplaceCatalogSyncCronJob` via the message queue - Uses `@InjectMessageQueue` decorator to inject the cron queue service - Includes job deduplication via `id: 'marketplace-catalog-sync'` to prevent multiple pending sync jobs - Protected with `@UseGuards(AdminPanelGuard)` for admin-only access - **GraphQL Schema**: - Added `SyncMarketplaceCatalog` mutation type definition - Generated corresponding TypeScript types and mutation document - **New Files**: - Created `syncMarketplaceCatalog.ts` GraphQL mutation document <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/22260?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
@@ -65,6 +65,7 @@ import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/service
|
||||
import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter';
|
||||
import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe';
|
||||
import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { MarketplaceCatalogSyncCronJob } from 'src/engine/core-modules/application/application-marketplace/crons/marketplace-catalog-sync.cron.job';
|
||||
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
|
||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
|
||||
@@ -139,8 +140,10 @@ export class AdminPanelResolver {
|
||||
private readonly upgradeStatusService: UpgradeStatusService,
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
@InjectMessageQueue(MessageQueue.cronQueue)
|
||||
private readonly cronQueueService: MessageQueueService,
|
||||
@InjectMessageQueue(MessageQueue.workspaceQueue)
|
||||
private readonly messageQueueService: MessageQueueService,
|
||||
private readonly workspaceQueueService: MessageQueueService,
|
||||
) {}
|
||||
|
||||
@UseGuards(AdminPanelOrImpersonateGuard)
|
||||
@@ -479,6 +482,18 @@ export class AdminPanelResolver {
|
||||
return this.applicationRegistrationService.findAll();
|
||||
}
|
||||
|
||||
@UseGuards(AdminPanelGuard)
|
||||
@Mutation(() => Boolean)
|
||||
async syncMarketplaceCatalog(): Promise<boolean> {
|
||||
await this.cronQueueService.add(
|
||||
MarketplaceCatalogSyncCronJob.name,
|
||||
{},
|
||||
{ id: 'marketplace-catalog-sync' }, // Avoids triggering multiple pending jobs
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@UseGuards(AdminPanelGuard)
|
||||
@Mutation(() => ApplicationRegistrationEntity)
|
||||
async updateAdminApplicationRegistration(
|
||||
@@ -503,7 +518,7 @@ export class AdminPanelResolver {
|
||||
);
|
||||
}
|
||||
|
||||
await this.messageQueueService.add<BackfillApplicationInstallationJobData>(
|
||||
await this.workspaceQueueService.add<BackfillApplicationInstallationJobData>(
|
||||
BACKFILL_APPLICATION_INSTALLATION_JOB_NAME,
|
||||
{ applicationRegistrationId },
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user