1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-10-27 11:02:16 +01:00

integration list placeholder

This commit is contained in:
Tymoteusz Czech 2023-08-21 17:06:16 +02:00
parent 50dc7ee57a
commit f2de69f306
No known key found for this signature in database
GPG Key ID: 133555230D88D75F
5 changed files with 86 additions and 56 deletions

View File

@ -1,5 +1,6 @@
import { type VFC } from 'react'; import { type VFC } from 'react';
import type { AddonTypeSchema } from 'openapi'; import type { AddonTypeSchema } from 'openapi';
import useLoading from 'hooks/useLoading';
import { PageContent } from 'component/common/PageContent/PageContent'; import { PageContent } from 'component/common/PageContent/PageContent';
import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { PageHeader } from 'component/common/PageHeader/PageHeader';
import { IntegrationCard } from '../IntegrationCard/IntegrationCard'; import { IntegrationCard } from '../IntegrationCard/IntegrationCard';
@ -7,13 +8,19 @@ import { StyledCardsGrid } from '../IntegrationList.styles';
interface IAvailableIntegrationsProps { interface IAvailableIntegrationsProps {
providers: AddonTypeSchema[]; providers: AddonTypeSchema[];
loading?: boolean;
} }
export const AvailableIntegrations: VFC<IAvailableIntegrationsProps> = ({ export const AvailableIntegrations: VFC<IAvailableIntegrationsProps> = ({
providers, providers,
loading,
}) => { }) => {
const ref = useLoading(loading || false);
return ( return (
<PageContent header={<PageHeader title="Available integrations" />}> <PageContent
<StyledCardsGrid> header={<PageHeader title="Available integrations" />}
isLoading={loading}
>
<StyledCardsGrid ref={ref}>
{providers?.map(({ name, displayName, description }) => ( {providers?.map(({ name, displayName, description }) => (
<IntegrationCard <IntegrationCard
key={name} key={name}

View File

@ -1,62 +1,59 @@
import { Table, TableBody, TableCell, TableRow } from 'component/common/Table'; import { AddonSchema, AddonTypeSchema } from 'openapi';
import { useMemo, useState, useCallback } from 'react'; import useLoading from 'hooks/useLoading';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { PageContent } from 'component/common/PageContent/PageContent'; import { PageContent } from 'component/common/PageContent/PageContent';
import useAddons from 'hooks/api/getters/useAddons/useAddons';
import useToast from 'hooks/useToast';
import useAddonsApi from 'hooks/api/actions/useAddonsApi/useAddonsApi';
import { Dialogue } from 'component/common/Dialogue/Dialogue';
import { formatUnknownError } from 'utils/formatUnknownError';
import { sortTypes } from 'utils/sortTypes';
import { useTable, useSortBy } from 'react-table';
import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { PageHeader } from 'component/common/PageHeader/PageHeader';
import { SortableTableHeader, TablePlaceholder } from 'component/common/Table';
import { IconCell } from 'component/common/Table/cells/IconCell/IconCell';
import { IntegrationIcon } from '../IntegrationIcon/IntegrationIcon';
import { IntegrationNameCell } from '../IntegrationNameCell/IntegrationNameCell';
import { StyledCardsGrid } from '../IntegrationList.styles'; import { StyledCardsGrid } from '../IntegrationList.styles';
import { IntegrationCard } from '../IntegrationCard/IntegrationCard'; import { IntegrationCard } from '../IntegrationCard/IntegrationCard';
import { VFC } from 'react';
export const ConfiguredIntegrations = () => { type ConfiguredIntegrationsProps = {
const { refetchAddons, addons, loading } = useAddons(); loading: boolean;
const { updateAddon, removeAddon } = useAddonsApi(); addons: AddonSchema[];
const { setToastData, setToastApiError } = useToast(); providers: AddonTypeSchema[];
const [showDelete, setShowDelete] = useState(false); };
const data = useMemo(() => {
if (loading) {
return Array(5).fill({
name: 'Addon name',
description: 'Addon description when loading',
});
}
return addons.map(addon => ({
...addon,
}));
}, [addons, loading]);
export const ConfiguredIntegrations: VFC<ConfiguredIntegrationsProps> = ({
loading,
addons,
providers,
}) => {
const counter = addons.length ? `(${addons.length})` : ''; const counter = addons.length ? `(${addons.length})` : '';
const ref = useLoading(loading || false);
return ( return (
<PageContent <PageContent
isLoading={loading}
header={<PageHeader title={`Configured integrations ${counter}`} />} header={<PageHeader title={`Configured integrations ${counter}`} />}
sx={theme => ({ marginBottom: theme.spacing(2) })} sx={theme => ({ marginBottom: theme.spacing(2) })}
isLoading={loading}
> >
<StyledCardsGrid> <StyledCardsGrid ref={ref}>
{addons?.map(({ id, enabled, provider, description }) => ( {addons?.map(
({
id,
enabled,
provider,
description,
// events,
// projects,
}) => {
const providerConfig = providers.find(
item => item.name === provider
);
return (
<IntegrationCard <IntegrationCard
key={id} key={id}
id={id} id={id}
icon={provider} icon={provider}
title={provider} title={providerConfig?.displayName || provider}
isEnabled={enabled} isEnabled={enabled}
description={description || ''} description={description || ''}
isConfigured isConfigured
link={`/integrations/edit/${id}`} link={`/integrations/edit/${id}`}
/> />
))} );
}
)}
</StyledCardsGrid> </StyledCardsGrid>
</PageContent> </PageContent>
); );

View File

@ -1,4 +1,4 @@
import { useState, VFC } from 'react'; import { VFC } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { styled, Typography } from '@mui/material'; import { styled, Typography } from '@mui/material';
import { IntegrationIcon } from '../IntegrationIcon/IntegrationIcon'; import { IntegrationIcon } from '../IntegrationIcon/IntegrationIcon';
@ -68,24 +68,30 @@ export const IntegrationCard: VFC<IIntegrationCardProps> = ({
return ( return (
<StyledLink to={link}> <StyledLink to={link}>
<StyledHeader> <StyledHeader>
<StyledTitle variant="h3"> <StyledTitle variant="h3" data-loading>
<IntegrationIcon name={icon as string} /> {title} <IntegrationIcon name={icon as string} /> {title}
</StyledTitle> </StyledTitle>
<ConditionallyRender <ConditionallyRender
condition={isEnabled === true} condition={isEnabled === true}
show={<Badge color="success">Enabled</Badge>} show={
<Badge color="success" data-loading>
Enabled
</Badge>
}
/> />
<ConditionallyRender <ConditionallyRender
condition={isEnabled === false} condition={isEnabled === false}
show={<Badge>Disabled</Badge>} show={<Badge data-loading>Disabled</Badge>}
/> />
<ConditionallyRender <ConditionallyRender
condition={isConfigured} condition={isConfigured}
show={<IntegrationCardMenu id={id as string} />} show={<IntegrationCardMenu id={id as string} />}
/> />
</StyledHeader> </StyledHeader>
<Typography variant="body1">{description}</Typography> <Typography variant="body1" data-loading>
<StyledAction> {description}
</Typography>
<StyledAction data-loading>
{configureActionText} <ChevronRightIcon /> {configureActionText} <ChevronRightIcon />
</StyledAction> </StyledAction>
</StyledLink> </StyledLink>

View File

@ -56,6 +56,7 @@ export const IntegrationCardMenu: VFC<IIntegrationCardMenuProps> = ({ id }) => {
aria-controls={open ? 'actions-menu' : undefined} aria-controls={open ? 'actions-menu' : undefined}
aria-haspopup="true" aria-haspopup="true"
aria-expanded={open ? 'true' : undefined} aria-expanded={open ? 'true' : undefined}
data-loading
> >
<MoreVertIcon sx={{ width: 32, height: 32 }} /> <MoreVertIcon sx={{ width: 32, height: 32 }} />
</IconButton> </IconButton>

View File

@ -3,17 +3,36 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
import useAddons from 'hooks/api/getters/useAddons/useAddons'; import useAddons from 'hooks/api/getters/useAddons/useAddons';
import { AvailableIntegrations } from './AvailableIntegrations/AvailableIntegrations'; import { AvailableIntegrations } from './AvailableIntegrations/AvailableIntegrations';
import { ConfiguredIntegrations } from './ConfiguredIntegrations/ConfiguredIntegrations'; import { ConfiguredIntegrations } from './ConfiguredIntegrations/ConfiguredIntegrations';
import { AddonSchema } from 'openapi';
export const IntegrationList: VFC = () => { export const IntegrationList: VFC = () => {
const { providers, addons, loading } = useAddons(); const { providers, addons, loading } = useAddons();
const loadingPlaceholderAddons: AddonSchema[] = Array.from({ length: 4 })
.fill({})
.map((_, id) => ({
id,
provider: 'mock',
description: 'mock integratino',
events: [],
projects: [],
parameters: {},
enabled: false,
}));
return ( return (
<> <>
<ConditionallyRender <ConditionallyRender
condition={addons.length > 0} condition={addons.length > 0}
show={<ConfiguredIntegrations />} show={
<ConfiguredIntegrations
addons={loading ? loadingPlaceholderAddons : addons}
providers={providers}
loading={loading}
/> />
<AvailableIntegrations providers={providers} /> }
/>
<AvailableIntegrations providers={providers} loading={loading} />
</> </>
); );
}; };