From c9012d5e6dda8b7eda44a2466d51b2a5eea979a5 Mon Sep 17 00:00:00 2001 From: Jono M Date: Tue, 15 Aug 2023 12:41:58 +0100 Subject: [PATCH] Added API call to load integrations into AdminX (#17720) no issue --- apps/admin-x-settings/src/api/integrations.ts | 82 +++++++++++++++++++ .../settings/advanced/Integrations.tsx | 24 +++--- 2 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 apps/admin-x-settings/src/api/integrations.ts diff --git a/apps/admin-x-settings/src/api/integrations.ts b/apps/admin-x-settings/src/api/integrations.ts new file mode 100644 index 0000000000..5c673b89ec --- /dev/null +++ b/apps/admin-x-settings/src/api/integrations.ts @@ -0,0 +1,82 @@ +import {Meta, createQuery} from '../utils/apiRequests'; + +// Types + +export type IntegrationApiKey = { + id: string; + type: string; + secret: string; + role_id: string; + integration_id: string; + user_id: string | null; + last_seen_at: string | null; + last_seen_version: string | null; + created_at: string; + updated_at: string; +} + +export type IntegrationWebhook = { + id: string; + event: string; + target_url: string; + name: string; + secret: string | null; + api_version: string; + integration_id: string; + last_triggered_at: string | null; + last_triggered_status: string | null; + last_triggered_error: string | null; + created_at: string; + updated_at: string; +} + +export type Integration = { + id: string; + type: 'builtin' | 'core' | 'custom'; + name: string; + slug: string; + icon_image: string | null; + description: string; + created_at: string; + updated_at: string; + api_keys: IntegrationApiKey[]; + webhooks: IntegrationWebhook[]; +} + +export interface IntegrationsResponseType { + meta?: Meta; + integrations: Integration[]; +} + +// Requests + +const dataType = 'IntegrationsResponseType'; + +export const useBrowseIntegrations = createQuery({ + dataType, + path: '/integrations/', + defaultSearchParams: {include: 'api_keys,webhooks'} +}); + +// export const useEditIntegration = createMutation({ +// method: 'PUT', +// path: integration => `/integrations/${integration.id}/`, +// body: integration => ({integrations: [integration]}), +// searchParams: () => ({include: 'roles'}), +// updateQueries: { +// dataType, +// update: () => {} // TODO +// } +// }); + +// export const useDeleteIntegration = createMutation({ +// method: 'DELETE', +// path: id => `/integrations/${id}/`, +// updateQueries: { +// dataType, +// update: (_, currentData, id) => ({ +// ...(currentData as IntegrationsResponseType), +// integrations: (currentData as IntegrationsResponseType).integrations.filter(user => user.id !== id) +// }) +// } +// }); diff --git a/apps/admin-x-settings/src/components/settings/advanced/Integrations.tsx b/apps/admin-x-settings/src/components/settings/advanced/Integrations.tsx index 9376491c87..c1639c97df 100644 --- a/apps/admin-x-settings/src/components/settings/advanced/Integrations.tsx +++ b/apps/admin-x-settings/src/components/settings/advanced/Integrations.tsx @@ -7,12 +7,13 @@ import TabView from '../../../admin-x-ds/global/TabView'; import useRouting from '../../../hooks/useRouting'; import {ReactComponent as AmpIcon} from '../../../assets/icons/amp.svg'; import {ReactComponent as FirstPromoterIcon} from '../../../assets/icons/firstpromoter.svg'; +import {Integration, useBrowseIntegrations} from '../../../api/integrations'; import {ReactComponent as PinturaIcon} from '../../../assets/icons/pintura.svg'; import {ReactComponent as SlackIcon} from '../../../assets/icons/slack.svg'; import {ReactComponent as UnsplashIcon} from '../../../assets/icons/unsplash.svg'; import {ReactComponent as ZapierIcon} from '../../../assets/icons/zapier.svg'; -const Integration: React.FC<{icon?: React.ReactNode, title: string, detail:string, action:() => void}> = ({ +const IntegrationItem: React.FC<{icon?: React.ReactNode, title: string, detail:string, action:() => void}> = ({ icon, title, detail, @@ -36,7 +37,7 @@ const BuiltInIntegrations: React.FC = () => { return ( - { openModal('integrations/zapier'); }} @@ -44,7 +45,7 @@ const BuiltInIntegrations: React.FC = () => { icon={} title='Zapier' /> - { openModal('integrations/slack'); }} @@ -52,7 +53,7 @@ const BuiltInIntegrations: React.FC = () => { icon={} title='Slack' /> - { openModal('integrations/amp'); }} @@ -60,7 +61,7 @@ const BuiltInIntegrations: React.FC = () => { icon={} title='AMP' /> - { openModal('integrations/unsplash'); }} @@ -68,7 +69,7 @@ const BuiltInIntegrations: React.FC = () => { icon={} title='Unsplash' /> - { openModal('integrations/firstpromoter'); }} @@ -76,7 +77,7 @@ const BuiltInIntegrations: React.FC = () => { icon={} title='FirstPromoter' /> - { openModal('integrations/pintura'); }} @@ -87,16 +88,19 @@ const BuiltInIntegrations: React.FC = () => { ); }; -const CustomIntegrations: React.FC = () => { +const CustomIntegrations: React.FC<{integrations: Integration[]}> = ({integrations}) => { return ( - {}} detail='Here we go' title='A custom integration' /> + {integrations.map(integration => ( + {}} detail={integration.description || 'No description'} title={integration.name} />) + )} ); }; const Integrations: React.FC<{ keywords: string[] }> = ({keywords}) => { const [selectedTab, setSelectedTab] = useState<'built-in' | 'custom'>('built-in'); + const {data: {integrations} = {integrations: []}} = useBrowseIntegrations(); const tabs = [ { @@ -107,7 +111,7 @@ const Integrations: React.FC<{ keywords: string[] }> = ({keywords}) => { { id: 'custom', title: 'Custom', - contents: + contents: integration.type === 'custom')} /> } ] as const;