config-ui/src/routes/connection/connections.tsx (158 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { useState, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { theme, Badge, Modal } from 'antd'; import { chunk } from 'lodash'; import { selectPlugins, selectAllConnections, selectWebhooks } from '@/features/connections'; import { PATHS } from '@/config'; import { useAppSelector } from '@/hooks'; import { getPluginConfig, ConnectionList, ConnectionForm } from '@/plugins'; import * as S from './styled'; const SORT_START_WITH = ['o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; export const Connections = () => { const [type, setType] = useState<'list' | 'form'>(); const [plugin, setPlugin] = useState(''); const { token: { colorPrimary }, } = theme.useToken(); const pluginConfig = useMemo(() => getPluginConfig(plugin), [plugin]); const navigate = useNavigate(); const plugins = useAppSelector(selectPlugins); const connections = useAppSelector(selectAllConnections); const webhooks = useAppSelector(selectWebhooks); const filterWebhookPlugins = plugins.filter((p) => p !== 'webhook'); const index = filterWebhookPlugins.findIndex((p) => SORT_START_WITH.includes(p[0])); const [firstPlugins, secondPlugins] = useMemo(() => { if (index > 0) { return chunk(filterWebhookPlugins, index); } return [filterWebhookPlugins, []]; }, [index]); const handleShowListDialog = (plugin: string) => { setType('list'); setPlugin(plugin); }; const handleShowFormDialog = () => { setType('form'); }; const handleHideDialog = () => { setType(undefined); setPlugin(''); }; const handleSuccessAfter = async (plugin: string, id: ID) => { navigate(PATHS.CONNECTION(plugin, id)); }; return ( <S.Wrapper theme={colorPrimary}> <h1>Connections</h1> <h5> Create and manage data connections from the following data sources or Webhooks to be used in syncing data in your Projects. </h5> <h2>Data Connections</h2> <h5>You can create and manage data connections for the following data sources and use them in your Projects.</h5> <h4>A-N</h4> <ul> {firstPlugins.map((plugin) => { const pluginConfig = getPluginConfig(plugin); const connectionCount = connections.filter((cs) => cs.plugin === plugin).length; return ( <li key={plugin} onClick={() => handleShowListDialog(plugin)}> {pluginConfig.isBeta && <span className="beta">Beta</span>} <span className="logo">{pluginConfig.icon({ color: colorPrimary })}</span> <span className="name">{pluginConfig.name}</span> <span className="count"> {connectionCount ? ( <Badge color={colorPrimary} text={`${connectionCount} connections`} /> ) : ( 'No connection' )} </span> </li> ); })} </ul> <h4>O-Z</h4> <ul> {secondPlugins.map((plugin) => { const pluginConfig = getPluginConfig(plugin); const connectionCount = connections.filter((cs) => cs.plugin === plugin).length; return ( <li key={plugin} onClick={() => handleShowListDialog(plugin)}> {pluginConfig.isBeta && <span className="beta">Beta</span>} <span className="logo">{pluginConfig.icon({ color: colorPrimary })}</span> <span className="name">{pluginConfig.name}</span> <span className="count"> {connectionCount ? ( <Badge color={colorPrimary} text={`${connectionCount} connections`} /> ) : ( 'No connection' )} </span> </li> ); })} </ul> <h2>Webhooks</h2> <h5> You can use webhooks to import deployments and incidents from the unsupported data integrations to calculate DORA metrics, etc. </h5> <ul> {plugins .filter((plugin) => plugin === 'webhook') .map((plugin) => { const pluginConfig = getPluginConfig(plugin); const connectionCount = webhooks.length; return ( <li key={plugin} onClick={() => handleShowListDialog(plugin)}> <span className="logo">{pluginConfig.icon({ color: colorPrimary })}</span> <span className="name">{pluginConfig.name}</span> <span className="count"> {connectionCount ? ( <Badge color={colorPrimary} text={`${connectionCount} connections`} /> ) : ( 'No connection' )} </span> </li> ); })} </ul> {type === 'list' && pluginConfig && ( <Modal open width={820} centered title={ <S.ModalTitle> <span className="icon">{pluginConfig.icon({ color: colorPrimary })}</span> <span className="name">Manage Connections: {pluginConfig.name}</span> </S.ModalTitle> } footer={null} onCancel={handleHideDialog} > <ConnectionList plugin={pluginConfig.plugin} onCreate={handleShowFormDialog} /> </Modal> )} {type === 'form' && pluginConfig && ( <Modal open width={820} centered title={ <S.ModalTitle> <span className="icon">{pluginConfig.icon({ color: colorPrimary })}</span> <span className="name">Manage Connections: {pluginConfig.name}</span> </S.ModalTitle> } footer={null} onCancel={handleHideDialog} > <ConnectionForm plugin={pluginConfig.plugin} onSuccess={(id) => handleSuccessAfter(pluginConfig.plugin, id)} /> </Modal> )} </S.Wrapper> ); };