Skip to content

Commit cd64f1d

Browse files
feat(frontend): add reusable EmptyState component for empty pages (#6538)
1 parent f5f81e3 commit cd64f1d

4 files changed

Lines changed: 78 additions & 0 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { FC, ReactNode } from 'react'
2+
import Icon, { IconName } from './Icon'
3+
4+
type EmptyStateProps = {
5+
title: string
6+
description?: string | ReactNode
7+
icon?: IconName
8+
iconColour?: string
9+
docsUrl?: string
10+
docsLabel?: string
11+
action?: ReactNode
12+
className?: string
13+
}
14+
15+
const EmptyState: FC<EmptyStateProps> = ({
16+
action,
17+
className,
18+
description,
19+
docsLabel = 'View docs',
20+
docsUrl,
21+
icon,
22+
iconColour = '#9DA4AE',
23+
title,
24+
}) => {
25+
return (
26+
<div className={`empty-state ${className || ''}`}>
27+
{icon && (
28+
<div className='empty-state__icon'>
29+
<Icon name={icon} width={40} fill={iconColour} />
30+
</div>
31+
)}
32+
<h5 className='empty-state__title'>{title}</h5>
33+
{description && (
34+
<div className='empty-state__description text-muted'>{description}</div>
35+
)}
36+
{docsUrl && (
37+
<a
38+
href={docsUrl}
39+
target='_blank'
40+
rel='noreferrer'
41+
className='btn btn-link'
42+
>
43+
{docsLabel}
44+
</a>
45+
)}
46+
{action}
47+
</div>
48+
)
49+
}
50+
51+
export default EmptyState

frontend/web/components/pages/ScheduledChangesPage.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import PlanBasedBanner, {
1313
featureDescriptions,
1414
} from 'components/PlanBasedAccess'
1515
import PanelSearch from 'components/PanelSearch'
16+
import EmptyState from 'components/EmptyState'
1617
import JSONReference from 'components/JSONReference'
1718
import Icon from 'components/Icon'
1819
import getUserDisplayName from 'common/utils/getUserDisplayName'
@@ -83,6 +84,14 @@ const ScheduledChangesPage: FC<ScheduledChangesPageType> = ({ match }) => {
8384
isLoading={isLoading || !dataScheduled || !organisation}
8485
paging={dataScheduled}
8586
items={dataScheduled?.results}
87+
renderNoResults={
88+
<EmptyState
89+
icon='calendar'
90+
title='No scheduled changes'
91+
description='To schedule a change, edit a feature flag and use the "Schedule" option when saving your changes.'
92+
docsUrl={featureDescriptions.SCHEDULE_FLAGS.docs}
93+
/>
94+
}
8695
renderFooter={() => (
8796
<JSONReference
8897
className='mt-4 ml-3'
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.empty-state {
2+
text-align: center;
3+
padding: 2rem 1rem;
4+
5+
&__icon {
6+
margin-bottom: 1rem;
7+
}
8+
9+
&__title {
10+
margin-bottom: 0.5rem;
11+
}
12+
13+
&__description {
14+
max-width: 400px;
15+
margin: 0 auto 1rem;
16+
}
17+
}

frontend/web/styles/components/_index.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
@import 'feature-pipeline-status';
1717
@import 'button-dropdown';
1818
@import 'feature-row-skeleton';
19+
@import 'empty-state';

0 commit comments

Comments
 (0)