Skip to content

Commit

Permalink
feat(ldp): subscriptions list implementation
Browse files Browse the repository at this point in the history
ref: MANAGER-15919

Signed-off-by: Vincent BONMARCHAND <[email protected]>
  • Loading branch information
vovh committed Dec 18, 2024
1 parent a77538a commit 1a57d49
Show file tree
Hide file tree
Showing 30 changed files with 689 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { CommonTitle, LinkType, Links } from '@ovh-ux/manager-react-components';
import {
ODS_BUTTON_SIZE,
ODS_BUTTON_VARIANT,
ODS_TEXT_COLOR_INTENT,
ODS_TEXT_LEVEL,
ODS_TEXT_SIZE,
} from '@ovhcloud/ods-components';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { OsdsTile, OsdsText, OsdsButton } from '@ovhcloud/ods-components/react';
import React from 'react';
import { useTranslation } from 'react-i18next';

const SubscriptionEmpty = () => {
const { t } = useTranslation('logSubscription');

return (
<OsdsTile rounded inline className="flex flex-col w-full h-fit">
<div className="flex flex-col gap-6 pb-4">
<CommonTitle>{t('log_subscription_empty_tile_title')}</CommonTitle>
<OsdsText
color={ODS_TEXT_COLOR_INTENT.text}
level={ODS_TEXT_LEVEL.body}
size={ODS_TEXT_SIZE._200}
>
{t('log_subscription_empty_tile_description')}
</OsdsText>
<Links
type={LinkType.external}
label={t('log_subscription_empty_tile_button_know_more')}
/>
<OsdsButton
inline
variant={ODS_BUTTON_VARIANT.stroked}
color={ODS_THEME_COLOR_INTENT.primary}
size={ODS_BUTTON_SIZE.sm}
>
{t('log_subscription_empty_tile_button_subscribe')}
</OsdsButton>
</div>
</OsdsTile>
);
};

export default SubscriptionEmpty;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { CommonTitle } from '@ovh-ux/manager-react-components';
import { ODS_THEME_TYPOGRAPHY_SIZE } from '@ovhcloud/ods-common-theming';
import { useLogService } from '../../data/hooks/useLogService';
import { LogSubscription } from '../../data/types/dbaas/logs';

type SubscriptionLogServiceProps = {
subscription: LogSubscription;
};

const SubscriptionLogService = ({
subscription,
}: SubscriptionLogServiceProps) => {
const { t } = useTranslation('logService');
const { data } = useLogService(subscription.serviceName);
return (
<>
<div className="flex flex-col gap-3">
<div className="flex flex-row justify-between ">
<CommonTitle typoSize={ODS_THEME_TYPOGRAPHY_SIZE._200}>
{data?.data.displayName || subscription.serviceName}
</CommonTitle>
{subscription.serviceName}
</div>
</div>
<div className="flex flex-col gap-3">
<div className="flex flex-row justify-between ">
<CommonTitle typoSize={ODS_THEME_TYPOGRAPHY_SIZE._200}>
{t('log_service_username_tile_label')}
</CommonTitle>
{data?.data.username}
</div>
</div>
</>
);
};

export default SubscriptionLogService;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { ManagerButton } from '@ovh-ux/manager-react-components';
import { useTranslation } from 'react-i18next';
import {
ODS_BUTTON_VARIANT,
ODS_ICON_NAME,
ODS_ICON_SIZE,
} from '@ovhcloud/ods-components';
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import { OsdsButton, OsdsIcon } from '@ovhcloud/ods-components/react';
import { useLogStreamUrl } from '../../data/hooks/useLogStreamUrl';
import { LogSubscription } from '../../data/types/dbaas/logs';

type SubscriptionStreamItemProps = {
subscription: LogSubscription;
};

const SubscriptionStreamActions = ({
subscription,
}: SubscriptionStreamItemProps) => {
const { data } = useLogStreamUrl(
subscription.serviceName,
subscription.streamId,
);
const { t } = useTranslation('logStream');
const { t: tSubscription } = useTranslation('logSubscription');
return (
<>
<OsdsButton
href={data?.data[0].address}
className="flex w-full"
color={ODS_THEME_COLOR_INTENT.primary}
variant={ODS_BUTTON_VARIANT.stroked}
>
{t('log_stream_button_graylog_watch_label')}
<span slot="end">
<OsdsIcon
name={ODS_ICON_NAME.EXTERNAL_LINK}
size={ODS_ICON_SIZE.xs}
color={ODS_THEME_COLOR_INTENT.primary}
></OsdsIcon>
</span>
</OsdsButton>
<OsdsButton
href={data?.data[0].address}
className="flex w-full"
variant={ODS_BUTTON_VARIANT.ghost}
color={ODS_THEME_COLOR_INTENT.primary}
>
{tSubscription('log_subscription_button_unsubscribe_label')}
</OsdsButton>
</>
);
};

export default SubscriptionStreamActions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { CommonTitle } from '@ovh-ux/manager-react-components';
import { ODS_THEME_TYPOGRAPHY_SIZE } from '@ovhcloud/ods-common-theming';
import { useLogStream } from '../../data/hooks/useLogStream';
import { LogSubscription } from '../../data/types/dbaas/logs';

type SubscriptionStreamItemProps = {
subscription: LogSubscription;
};

const SubscriptionStreamTitle = ({
subscription,
}: SubscriptionStreamItemProps) => {
const { t } = useTranslation('logStream');
const { data } = useLogStream(
subscription.serviceName,
subscription.streamId,
);
return (
<div className="flex flex-col gap-3">
<div className="flex flex-row justify-between ">
<CommonTitle typoSize={ODS_THEME_TYPOGRAPHY_SIZE._200}>
{t('log_stream_title_tile_label')}
</CommonTitle>
{data?.data.title}
</div>
</div>
);
};

export default SubscriptionStreamTitle;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { CommonTitle } from '@ovh-ux/manager-react-components';
import { OsdsDivider, OsdsTile } from '@ovhcloud/ods-components/react';
import { ODS_DIVIDER_SIZE } from '@ovhcloud/ods-components';
import { useTranslation } from 'react-i18next';
import { LogSubscription } from '../../data/types/dbaas/logs';
import SubscriptionStreamTitle from './SubscriptionStreamTitle.component';
import SubscriptionStreamActions from './SubscriptionStreamActions.component';
import SubscriptionLogService from './SubscriptionLogService.component';

type SubscriptionTileProps = {
subscription: LogSubscription;
};

const SubscriptionTile = ({ subscription }: SubscriptionTileProps) => {
const { t } = useTranslation('logSubscription');

return (
<OsdsTile rounded inline className="flex flex-col w-full h-fit">
<div className="flex flex-col gap-6 pb-4">
<CommonTitle>{t('log_subscription_tile_title')}</CommonTitle>
<SubscriptionLogService
subscription={subscription}
></SubscriptionLogService>
<SubscriptionStreamTitle
subscription={subscription}
></SubscriptionStreamTitle>
<OsdsDivider separator size={ODS_DIVIDER_SIZE.one} />
<SubscriptionStreamActions
subscription={subscription}
></SubscriptionStreamActions>
</div>
</OsdsTile>
);
};

export default SubscriptionTile;
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, { useContext } from 'react';
import { OsdsSpinner } from '@ovhcloud/ods-components/react';
import { ODS_SPINNER_SIZE } from '@ovhcloud/ods-components';
import { useQueryClient } from '@tanstack/react-query';
import { LogsContext } from '../../LogsToCustomer.context';
import {
getLogSubscriptionsQueryKey,
useLogSubscriptions,
} from '../../data/hooks/useLogSubscriptions';
import SubscriptionTile from './SubscriptionTile.component';
import SubscriptionEmpty from './SubscriptionEmpty.component';
import ApiError from '../apiError/ApiError.component';

export default function LogsSubscriptions() {
const queryClient = useQueryClient();
const { currentLogKind, logApiUrls, logApiVersion } = useContext(LogsContext);
const { data, isLoading, isPending, error } = useLogSubscriptions(
logApiUrls.logSubscription,
logApiVersion,
currentLogKind,
);

if (!currentLogKind) {
return (
<div className="flex py-8">
<OsdsSpinner
inline
size={ODS_SPINNER_SIZE.md}
data-testid="logCurrentLogKind-spinner"
/>
</div>
);
}

if (isLoading || isPending)
return (
<div className="flex py-8">
<OsdsSpinner
inline
size={ODS_SPINNER_SIZE.md}
data-testid="logSubscriptions-spinner"
/>
</div>
);

if (error)
return (
<ApiError
error={error}
onRetry={() =>
queryClient.refetchQueries({
queryKey: getLogSubscriptionsQueryKey(
logApiUrls.logSubscription,
currentLogKind,
),
})
}
/>
);

if (data?.length === 0) return <SubscriptionEmpty />;

return (
<div className="flex gap-8 flex-col p-8">
{data.map((subscription) => (
<SubscriptionTile
key={subscription.subscriptionId}
subscription={subscription}
/>
))}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { screen, waitFor } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { renderTest } from '../../test-utils';

describe('Subscription list', () => {
it('should display an error if /log/kind api is KO', async () => {
await renderTest({ isLogKindsKO: true });

await waitFor(() => expect(screen.getByText('error_title')).toBeDefined(), {
timeout: 10_000,
});
});

it('should render a loading state when the kinds api request is pending', async () => {
await renderTest();

expect(screen.getByTestId('logKinds-spinner')).toBeVisible();
});

it('should display an error if /log/subscription api is KO', async () => {
await renderTest({ isLogSubscriptionKO: true });

await waitFor(() => expect(screen.getByText('error_title')).toBeDefined(), {
timeout: 10_000,
});
});

it('should render an empty state when there is no subscriptions', async () => {
await renderTest({ nbLogSubscription: 0 });

await waitFor(
() =>
expect(
screen.getByText('log_subscription_empty_tile_description'),
).toBeDefined(),
{
timeout: 10_000,
},
);
});
it('should render two subscriptions tile', async () => {
await renderTest({ nbLogSubscription: 2 });

await waitFor(
() =>
expect(screen.getAllByText('log_subscription_tile_title')).toHaveLength(
2,
),
{
timeout: 10_000,
},
);
});
});

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import apiClient from '@ovh-ux/manager-core-api';
import { LogService } from '../types/dbaas/logs/LogService';

/**
* GET log service infos
*/
export const getLogServicev6 = async (serviceName: string) =>
apiClient.v6.get<LogService>(`/dbaas/logs/${serviceName}`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import apiClient from '@ovh-ux/manager-core-api';
import { LogStream } from '../types/dbaas/logs/LogStream';

/**
* GET log stream
*/
export const getLogStreamv6 = async (serviceName: string, streamId: string) =>
apiClient.v6.get<LogStream>(
`/dbaas/logs/${serviceName}/output/graylog/stream/${streamId}`,
);
Loading

0 comments on commit 1a57d49

Please sign in to comment.