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:
@@ -415,6 +415,7 @@ export type Mutation = {
|
||||
setAdminAiModelsRecommended: Scalars['Boolean']['output'];
|
||||
setAdminDefaultAiModel: Scalars['Boolean']['output'];
|
||||
setMaintenanceMode: Scalars['Boolean']['output'];
|
||||
syncMarketplaceCatalog: Scalars['Boolean']['output'];
|
||||
updateAdminApplicationRegistration: ApplicationRegistration;
|
||||
updateAdminApplicationRegistrationVariable: ApplicationRegistrationVariableDto;
|
||||
updateDatabaseConfigVariable: Scalars['Boolean']['output'];
|
||||
@@ -1007,6 +1008,11 @@ export type BackfillApplicationInstallationMutationVariables = Exact<{
|
||||
|
||||
export type BackfillApplicationInstallationMutation = { __typename?: 'Mutation', backfillApplicationInstallation: boolean };
|
||||
|
||||
export type SyncMarketplaceCatalogMutationVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type SyncMarketplaceCatalogMutation = { __typename?: 'Mutation', syncMarketplaceCatalog: boolean };
|
||||
|
||||
export type UpdateAdminApplicationRegistrationMutationVariables = Exact<{
|
||||
input: UpdateApplicationRegistrationInput;
|
||||
}>;
|
||||
@@ -1268,6 +1274,7 @@ export const GetAiProvidersDocument = {"kind":"Document","definitions":[{"kind":
|
||||
export const GetModelsDevProvidersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetModelsDevProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getModelsDevProviders"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"modelCount"}},{"kind":"Field","name":{"kind":"Name","value":"npm"}}]}}]}}]} as unknown as DocumentNode<GetModelsDevProvidersQuery, GetModelsDevProvidersQueryVariables>;
|
||||
export const GetModelsDevSuggestionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetModelsDevSuggestions"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"providerType"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getModelsDevSuggestions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"providerType"},"value":{"kind":"Variable","name":{"kind":"Name","value":"providerType"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"modelId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"inputCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"outputCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"cachedInputCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"cacheCreationCostPerMillionTokens"}},{"kind":"Field","name":{"kind":"Name","value":"contextWindowTokens"}},{"kind":"Field","name":{"kind":"Name","value":"maxOutputTokens"}},{"kind":"Field","name":{"kind":"Name","value":"modalities"}},{"kind":"Field","name":{"kind":"Name","value":"supportsReasoning"}}]}}]}}]} as unknown as DocumentNode<GetModelsDevSuggestionsQuery, GetModelsDevSuggestionsQueryVariables>;
|
||||
export const BackfillApplicationInstallationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"BackfillApplicationInstallation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"applicationRegistrationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"backfillApplicationInstallation"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"applicationRegistrationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"applicationRegistrationId"}}}]}]}}]} as unknown as DocumentNode<BackfillApplicationInstallationMutation, BackfillApplicationInstallationMutationVariables>;
|
||||
export const SyncMarketplaceCatalogDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SyncMarketplaceCatalog"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"syncMarketplaceCatalog"}}]}}]} as unknown as DocumentNode<SyncMarketplaceCatalogMutation, SyncMarketplaceCatalogMutationVariables>;
|
||||
export const UpdateAdminApplicationRegistrationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateAdminApplicationRegistration"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateApplicationRegistrationInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateAdminApplicationRegistration"},"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":"ApplicationRegistrationFragment"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ApplicationRegistrationFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ApplicationRegistration"}},"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":"logoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"oAuthClientId"}},{"kind":"Field","name":{"kind":"Name","value":"oAuthRedirectUris"}},{"kind":"Field","name":{"kind":"Name","value":"oAuthScopes"}},{"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":"isPreInstalled"}},{"kind":"Field","name":{"kind":"Name","value":"isConfigured"}},{"kind":"Field","name":{"kind":"Name","value":"ownerWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<UpdateAdminApplicationRegistrationMutation, UpdateAdminApplicationRegistrationMutationVariables>;
|
||||
export const UpdateAdminApplicationRegistrationVariableDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateAdminApplicationRegistrationVariable"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateApplicationRegistrationVariableInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateAdminApplicationRegistrationVariable"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"isSecret"}},{"kind":"Field","name":{"kind":"Name","value":"isRequired"}},{"kind":"Field","name":{"kind":"Name","value":"isFilled"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<UpdateAdminApplicationRegistrationVariableMutation, UpdateAdminApplicationRegistrationVariableMutationVariables>;
|
||||
export const FindAdminApplicationRegistrationVariablesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindAdminApplicationRegistrationVariables"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"applicationRegistrationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findAdminApplicationRegistrationVariables"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"applicationRegistrationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"applicationRegistrationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"isSecret"}},{"kind":"Field","name":{"kind":"Name","value":"isRequired"}},{"kind":"Field","name":{"kind":"Name","value":"isFilled"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<FindAdminApplicationRegistrationVariablesQuery, FindAdminApplicationRegistrationVariablesQueryVariables>;
|
||||
|
||||
+98
-60
@@ -1,5 +1,6 @@
|
||||
import { AppChip } from '@/applications/components/AppChip';
|
||||
import { useApolloAdminClient } from '@/settings/admin-panel/apollo/hooks/useApolloAdminClient';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
@@ -8,15 +9,15 @@ import { TableBody } from '@/ui/layout/table/components/TableBody';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import { useQuery } from '@apollo/client/react';
|
||||
import { useMutation, useQuery } from '@apollo/client/react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { type ReactNode, useContext, useState } from 'react';
|
||||
import { assertUnreachable, getSettingsPath } from 'twenty-shared/utils';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { IconChevronRight, IconPinned } from 'twenty-ui/icon';
|
||||
import { IconChevronRight, IconPinned, IconRefresh } from 'twenty-ui/icon';
|
||||
import { H2Title } from 'twenty-ui/typography';
|
||||
import { SearchInput } from 'twenty-ui/input';
|
||||
import { Button, SearchInput } from 'twenty-ui/input';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
import { MenuItemToggle } from 'twenty-ui/navigation';
|
||||
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
@@ -25,6 +26,7 @@ import {
|
||||
type ApplicationRegistrationFragmentFragment,
|
||||
ApplicationRegistrationSourceType,
|
||||
FindAllApplicationRegistrationsDocument,
|
||||
SyncMarketplaceCatalogDocument,
|
||||
} from '~/generated-admin/graphql';
|
||||
|
||||
const StyledTableContainer = styled.div`
|
||||
@@ -37,6 +39,7 @@ const TABLE_GRID_MOBILE = '3fr 3fr 1fr 1fr 40px';
|
||||
|
||||
export const SettingsAdminApps = () => {
|
||||
const apolloAdminClient = useApolloAdminClient();
|
||||
const { enqueueSuccessSnackBar, enqueueErrorSnackBar } = useSnackBar();
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [showPreInstalledOnly, setShowPreInstalledOnly] = useState(false);
|
||||
|
||||
@@ -44,6 +47,24 @@ export const SettingsAdminApps = () => {
|
||||
client: apolloAdminClient,
|
||||
});
|
||||
|
||||
const [syncMarketplaceCatalog, { loading: isSyncing }] = useMutation(
|
||||
SyncMarketplaceCatalogDocument,
|
||||
{ client: apolloAdminClient },
|
||||
);
|
||||
|
||||
const handleSyncCatalog = async () => {
|
||||
try {
|
||||
await syncMarketplaceCatalog();
|
||||
enqueueSuccessSnackBar({
|
||||
message: t`Marketplace catalog synchronization started.`,
|
||||
});
|
||||
} catch {
|
||||
enqueueErrorSnackBar({
|
||||
message: t`Failed to synchronize the marketplace catalog.`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const registrations = data?.findAllApplicationRegistrations ?? [];
|
||||
|
||||
const query = searchQuery.trim().toLowerCase();
|
||||
@@ -88,63 +109,80 @@ export const SettingsAdminApps = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`All App Registrations`}
|
||||
description={t`All application registrations across the platform, including orphaned marketplace apps`}
|
||||
/>
|
||||
<SearchInput
|
||||
placeholder={t`Search registrations...`}
|
||||
value={searchQuery}
|
||||
onChange={setSearchQuery}
|
||||
filterDropdown={(filterButton: ReactNode) => (
|
||||
<Dropdown
|
||||
dropdownId="settings-admin-apps-filter-dropdown"
|
||||
dropdownPlacement="bottom-end"
|
||||
dropdownOffset={{ x: 0, y: 8 }}
|
||||
clickableComponent={filterButton}
|
||||
dropdownComponents={
|
||||
<DropdownContent>
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItemToggle
|
||||
LeftIcon={IconPinned}
|
||||
onToggleChange={() =>
|
||||
setShowPreInstalledOnly(!showPreInstalledOnly)
|
||||
}
|
||||
toggled={showPreInstalledOnly}
|
||||
text={t`Pre-installed only`}
|
||||
toggleSize="small"
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<StyledTableContainer>
|
||||
<Table>
|
||||
<TableRow
|
||||
gridAutoColumns={TABLE_GRID}
|
||||
mobileGridAutoColumns={TABLE_GRID_MOBILE}
|
||||
>
|
||||
<TableHeader>{t`Name`}</TableHeader>
|
||||
<TableHeader align="right">{t`Source`}</TableHeader>
|
||||
<TableHeader align="right">{t`Listed`}</TableHeader>
|
||||
<TableHeader align="right">{t`Configured`}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
<TableBody>
|
||||
{filtered.map((registration) => (
|
||||
<SettingsAdminAppsTableRow
|
||||
key={registration.id}
|
||||
registration={registration}
|
||||
getFormattedSource={getFormattedSource}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</StyledTableContainer>
|
||||
</Section>
|
||||
<>
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`General`}
|
||||
description={t`Manage the marketplace application catalog`}
|
||||
/>
|
||||
<Button
|
||||
Icon={IconRefresh}
|
||||
title={t`Synchronize catalog`}
|
||||
size="small"
|
||||
variant="secondary"
|
||||
onClick={handleSyncCatalog}
|
||||
isLoading={isSyncing}
|
||||
disabled={isSyncing}
|
||||
/>
|
||||
</Section>
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`All App Registrations`}
|
||||
description={t`All application registrations across the platform, including orphaned marketplace apps`}
|
||||
/>
|
||||
<SearchInput
|
||||
placeholder={t`Search registrations...`}
|
||||
value={searchQuery}
|
||||
onChange={setSearchQuery}
|
||||
filterDropdown={(filterButton: ReactNode) => (
|
||||
<Dropdown
|
||||
dropdownId="settings-admin-apps-filter-dropdown"
|
||||
dropdownPlacement="bottom-end"
|
||||
dropdownOffset={{ x: 0, y: 8 }}
|
||||
clickableComponent={filterButton}
|
||||
dropdownComponents={
|
||||
<DropdownContent>
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItemToggle
|
||||
LeftIcon={IconPinned}
|
||||
onToggleChange={() =>
|
||||
setShowPreInstalledOnly(!showPreInstalledOnly)
|
||||
}
|
||||
toggled={showPreInstalledOnly}
|
||||
text={t`Pre-installed only`}
|
||||
toggleSize="small"
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<StyledTableContainer>
|
||||
<Table>
|
||||
<TableRow
|
||||
gridAutoColumns={TABLE_GRID}
|
||||
mobileGridAutoColumns={TABLE_GRID_MOBILE}
|
||||
>
|
||||
<TableHeader>{t`Name`}</TableHeader>
|
||||
<TableHeader align="right">{t`Source`}</TableHeader>
|
||||
<TableHeader align="right">{t`Listed`}</TableHeader>
|
||||
<TableHeader align="right">{t`Configured`}</TableHeader>
|
||||
<TableHeader></TableHeader>
|
||||
</TableRow>
|
||||
<TableBody>
|
||||
{filtered.map((registration) => (
|
||||
<SettingsAdminAppsTableRow
|
||||
key={registration.id}
|
||||
registration={registration}
|
||||
getFormattedSource={getFormattedSource}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</StyledTableContainer>
|
||||
</Section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const SYNC_MARKETPLACE_CATALOG = gql`
|
||||
mutation SyncMarketplaceCatalog {
|
||||
syncMarketplaceCatalog
|
||||
}
|
||||
`;
|
||||
-1
@@ -3,7 +3,6 @@ import {
|
||||
FieldActorSource,
|
||||
type FullNameMetadata,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
type BuildCreatedByFromFullNameMetadataArgs = {
|
||||
workspaceMemberId: string;
|
||||
|
||||
@@ -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