Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ChangelogDialog): loading state #120

Merged
merged 11 commits into from
Jan 9, 2024
9 changes: 9 additions & 0 deletions src/components/ChangelogDialog/ChangelogDialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,13 @@ $maxItemsHeight: 70vh;
color: var(--g-color-text-secondary);
text-align: center;
}

&__loading {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
height: 70vh;
width: 100%;
}
}
41 changes: 28 additions & 13 deletions src/components/ChangelogDialog/ChangelogDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import React from 'react';

import {ArrowUpRightFromSquare} from '@gravity-ui/icons';
import type {DialogProps} from '@gravity-ui/uikit';
import {Dialog, Icon, Link} from '@gravity-ui/uikit';
import {Dialog, Icon, Link, Loader} from '@gravity-ui/uikit';

import {block} from '../utils/cn';

import {ErrorContainer} from './components/ErrorContainer/ErrorContainer';
import {Item} from './components/Item/Item';
import i18n from './i18n';
import type {ChangelogItem} from './types';
Expand All @@ -24,6 +25,9 @@ export interface ChangelogDialogProps {
onClose: DialogProps['onClose'];
onLinkClick?: (link: string) => void;
onStoryClick?: (storyId: string) => void;
onRetryClick?: () => void;
loading?: boolean;
error?: boolean | {title: string; description: string};
}

let nextId = 1;
Expand All @@ -41,6 +45,9 @@ export function ChangelogDialog({
onClose,
onStoryClick,
onLinkClick,
onRetryClick,
loading,
error,
}: ChangelogDialogProps) {
const idRef = React.useRef<number>();
idRef.current = idRef.current || getNextId();
Expand All @@ -67,19 +74,27 @@ export function ChangelogDialog({
</Dialog.Body>
) : null}
<Dialog.Body key="items" className={b('items-container')}>
{items.length > 0 ? (
items.map((item, index) => (
<Item
key={index}
className={b('item')}
data={item}
onStoryClick={onStoryClick}
onLinkClick={onLinkClick}
/>
))
) : (
<div className={b('empty-placeholder')}>{i18n('label_empty')}</div>
{loading && (
<div className={b('loading')}>
<Loader size={'m'} />
</div>
)}
{error && !loading && <ErrorContainer error={error} onRetryClick={onRetryClick} />}
{!error &&
!loading &&
(items.length > 0 ? (
items.map((item, index) => (
<Item
key={index}
className={b('item')}
data={item}
onStoryClick={onStoryClick}
onLinkClick={onLinkClick}
/>
))
) : (
<div className={b('empty-placeholder')}>{i18n('label_empty')}</div>
))}
</Dialog.Body>
</Dialog>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ const DefaultTemplate: StoryFn<ChangelogDialogProps> = (props: ChangelogDialogPr
};

export const Default = DefaultTemplate.bind({});

Default.args = {
open: false,
items,
Expand All @@ -121,4 +120,21 @@ Default.args = {
onClose: () => {
console.log('close');
},
onRetryClick: () => {
console.log('retry');
},
};

export const Loading = DefaultTemplate.bind({});
Loading.args = {
...Default.args,
open: true,
loading: true,
};

export const Error = DefaultTemplate.bind({});
Error.args = {
...Default.args,
open: true,
error: true,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';

import {Alert} from '@gravity-ui/uikit';

import i18n from '../../i18n';

interface ErrorContainerProps {
onRetryClick?: () => void;
error?: boolean | {title?: string; description?: string};
}

export function ErrorContainer({onRetryClick, error}: ErrorContainerProps) {
const {title, description} = React.useMemo(() => {
return error && typeof error === 'object' ? error : {};
}, [error]);

return (
<Alert
title={title || i18n('label_error-title')}
message={description}
theme={'danger'}
actions={
onRetryClick && [
{
text: i18n('button_retry'),
handler: onRetryClick,
},
]
}
/>
);
}
4 changes: 3 additions & 1 deletion src/components/ChangelogDialog/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
"label_new": "New",
"button_view_story": "View story",
"label_empty": "No data",
"action_read-more": "Read more"
"action_read-more": "Read more",
"label_error-title": "Unable load changelog",
"button_retry": "Retry"
}
4 changes: 3 additions & 1 deletion src/components/ChangelogDialog/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
"label_new": "New",
"button_view_story": "Посмотреть сториз",
"label_empty": "Нет данных",
"action_read-more": "Читать далее"
"action_read-more": "Читать далее",
"label_error-title": "Не удалось загрузить список изменений",
"button_retry": "Повторить"
}
4 changes: 3 additions & 1 deletion src/components/ChangelogDialog/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import React from 'react';

interface ImageData {
src: string;
alt?: string;
Expand All @@ -9,7 +11,7 @@ export interface ChangelogItem {
isNew?: boolean;
title: string;
image?: ImageData;
description: string;
description: React.ReactNode;
storyId?: string;
link?: string;
}