mirror of
https://github.com/strapi/strapi.git
synced 2025-11-21 12:41:32 +00:00
Merge pull request #10934 from strapi/add-empty-state-components
Add empty state components
This commit is contained in:
commit
a42a3747f1
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CustomContentLayout, useFocusWhenNavigate } from '@strapi/helper-plugin';
|
import { useFocusWhenNavigate, NoPermissions as NoPermissionsCompo } from '@strapi/helper-plugin';
|
||||||
import { Main } from '@strapi/parts/Main';
|
import { Main } from '@strapi/parts/Main';
|
||||||
import { HeaderLayout } from '@strapi/parts/Layout';
|
import { ContentLayout, HeaderLayout } from '@strapi/parts/Layout';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import { getTrad } from '../../utils';
|
import { getTrad } from '../../utils';
|
||||||
|
|
||||||
@ -18,9 +18,9 @@ const NoPermissions = () => {
|
|||||||
defaultMessage: 'Content',
|
defaultMessage: 'Content',
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<CustomContentLayout canRead={false}>
|
<ContentLayout>
|
||||||
<div />
|
<NoPermissionsCompo />
|
||||||
</CustomContentLayout>
|
</ContentLayout>
|
||||||
</Main>
|
</Main>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import pick from 'lodash/pick';
|
|||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
import {
|
import {
|
||||||
CustomContentLayout,
|
|
||||||
Form,
|
Form,
|
||||||
GenericInput,
|
GenericInput,
|
||||||
SettingsPageTitle,
|
SettingsPageTitle,
|
||||||
@ -15,13 +14,14 @@ import {
|
|||||||
useFocusWhenNavigate,
|
useFocusWhenNavigate,
|
||||||
useNotification,
|
useNotification,
|
||||||
useOverlayBlocker,
|
useOverlayBlocker,
|
||||||
|
LoadingIndicatorPage,
|
||||||
} from '@strapi/helper-plugin';
|
} from '@strapi/helper-plugin';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { Formik } from 'formik';
|
import { Formik } from 'formik';
|
||||||
import { Box } from '@strapi/parts/Box';
|
import { Box } from '@strapi/parts/Box';
|
||||||
import { Button } from '@strapi/parts/Button';
|
import { Button } from '@strapi/parts/Button';
|
||||||
import { Grid, GridItem } from '@strapi/parts/Grid';
|
import { Grid, GridItem } from '@strapi/parts/Grid';
|
||||||
import { HeaderLayout } from '@strapi/parts/Layout';
|
import { HeaderLayout, ContentLayout } from '@strapi/parts/Layout';
|
||||||
import { H3 } from '@strapi/parts/Text';
|
import { H3 } from '@strapi/parts/Text';
|
||||||
import { Main } from '@strapi/parts/Main';
|
import { Main } from '@strapi/parts/Main';
|
||||||
import { Stack } from '@strapi/parts/Stack';
|
import { Stack } from '@strapi/parts/Stack';
|
||||||
@ -130,7 +130,7 @@ const EditPage = ({ canUpdate }) => {
|
|||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<Main labelledBy="title">
|
<Main labelledBy="title" aria-busy="true">
|
||||||
<SettingsPageTitle name="Users" />
|
<SettingsPageTitle name="Users" />
|
||||||
<HeaderLayout
|
<HeaderLayout
|
||||||
id="title"
|
id="title"
|
||||||
@ -141,7 +141,9 @@ const EditPage = ({ canUpdate }) => {
|
|||||||
}
|
}
|
||||||
title={title}
|
title={title}
|
||||||
/>
|
/>
|
||||||
<CustomContentLayout isLoading />
|
<ContentLayout>
|
||||||
|
<LoadingIndicatorPage />
|
||||||
|
</ContentLayout>
|
||||||
</Main>
|
</Main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -172,7 +174,7 @@ const EditPage = ({ canUpdate }) => {
|
|||||||
}
|
}
|
||||||
title={title}
|
title={title}
|
||||||
/>
|
/>
|
||||||
<CustomContentLayout isLoading={isLoading}>
|
<ContentLayout>
|
||||||
{data?.registrationToken && (
|
{data?.registrationToken && (
|
||||||
<Box paddingBottom={6}>
|
<Box paddingBottom={6}>
|
||||||
<MagicLink registrationToken={data.registrationToken} />
|
<MagicLink registrationToken={data.registrationToken} />
|
||||||
@ -243,7 +245,7 @@ const EditPage = ({ canUpdate }) => {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
</CustomContentLayout>
|
</ContentLayout>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
CustomContentLayout,
|
|
||||||
Search,
|
Search,
|
||||||
SettingsPageTitle,
|
SettingsPageTitle,
|
||||||
useRBAC,
|
useRBAC,
|
||||||
useNotification,
|
useNotification,
|
||||||
useFocusWhenNavigate,
|
useFocusWhenNavigate,
|
||||||
|
NoPermissions,
|
||||||
} from '@strapi/helper-plugin';
|
} from '@strapi/helper-plugin';
|
||||||
import { Button, Box, HeaderLayout, Main, Row } from '@strapi/parts';
|
import { Button, Box, HeaderLayout, Main, Row, ContentLayout } from '@strapi/parts';
|
||||||
import { Mail } from '@strapi/icons';
|
import { Mail } from '@strapi/icons';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
@ -85,7 +85,7 @@ const ListPage = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Main labelledBy="title">
|
<Main labelledBy="title" aria-busy={isLoading}>
|
||||||
<SettingsPageTitle name="Users" />
|
<SettingsPageTitle name="Users" />
|
||||||
<HeaderLayout
|
<HeaderLayout
|
||||||
id="title"
|
id="title"
|
||||||
@ -102,7 +102,8 @@ const ListPage = () => {
|
|||||||
{ number: total }
|
{ number: total }
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<CustomContentLayout canRead={canRead}>
|
<ContentLayout canRead={canRead}>
|
||||||
|
{!canRead && <NoPermissions />}
|
||||||
{status === 'error' && <div>TODO: An error occurred</div>}
|
{status === 'error' && <div>TODO: An error occurred</div>}
|
||||||
{canRead && (
|
{canRead && (
|
||||||
<>
|
<>
|
||||||
@ -129,7 +130,7 @@ const ListPage = () => {
|
|||||||
<PaginationFooter pagination={data?.pagination} />
|
<PaginationFooter pagination={data?.pagination} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</CustomContentLayout>
|
</ContentLayout>
|
||||||
{isModalOpened && <ModalForm onToggle={handleToggle} queryName={queryName} />}
|
{isModalOpened && <ModalForm onToggle={handleToggle} queryName={queryName} />}
|
||||||
</Main>
|
</Main>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -121,6 +121,11 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
|
|||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.c13 {
|
||||||
|
padding-right: 56px;
|
||||||
|
padding-left: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
.c14 {
|
.c14 {
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
@ -748,11 +753,6 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
|
|||||||
fill: #666687;
|
fill: #666687;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c13 {
|
|
||||||
padding-right: 56px;
|
|
||||||
padding-left: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c36 tr:last-of-type {
|
.c36 tr:last-of-type {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
@ -789,6 +789,7 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
<main
|
<main
|
||||||
|
aria-busy="true"
|
||||||
aria-labelledby="title"
|
aria-labelledby="title"
|
||||||
class="c0"
|
class="c0"
|
||||||
id="main-content"
|
id="main-content"
|
||||||
@ -861,7 +862,7 @@ describe('ADMIN | Pages | USERS | ListPage', () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="c13"
|
class="c1 c13"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="c1 c14"
|
class="c1 c14"
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { ContentLayout } from '@strapi/parts/Layout';
|
import { ContentLayout } from '@strapi/parts/Layout';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import EmptyStateLayout from '../EmptyStateLayout';
|
import EmptyStateLayout from '../EmptyStateLayout';
|
||||||
import LoadingIndicatorPage from '../LoadingIndicatorPage';
|
import LoadingIndicatorPage from '../LoadingIndicatorPage';
|
||||||
|
|
||||||
|
// TODO: REMOVE this component
|
||||||
const CustomContentLayout = ({
|
const CustomContentLayout = ({
|
||||||
action,
|
action,
|
||||||
canRead,
|
canRead,
|
||||||
@ -12,6 +13,12 @@ const CustomContentLayout = ({
|
|||||||
shouldShowEmptyState,
|
shouldShowEmptyState,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
|
useEffect(() => {
|
||||||
|
console.error(
|
||||||
|
'This component will soon be removed, please check out the PageTemplate in the storybook'
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
if (!canRead) {
|
if (!canRead) {
|
||||||
return (
|
return (
|
||||||
<ContentLayout>
|
<ContentLayout>
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
<!--- EmptyStateLayout.stories.mdx --->
|
||||||
|
|
||||||
|
import { Meta, ArgsTable, Canvas, Story } from '@storybook/addon-docs';
|
||||||
|
import { Main, Row, Button } from '@strapi/parts';
|
||||||
|
import NoContent from './index';
|
||||||
|
|
||||||
|
<Meta title="components/NoContent" />
|
||||||
|
|
||||||
|
# NoContent
|
||||||
|
|
||||||
|
This component is used to display an empty state.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story name="base">
|
||||||
|
<Main>
|
||||||
|
<NoContent
|
||||||
|
content={{
|
||||||
|
id: 'app.components.EmptyStateLayout.content-document',
|
||||||
|
defaultMessage: "There's no content",
|
||||||
|
}}
|
||||||
|
action={<Button>Add content</Button>}
|
||||||
|
/>
|
||||||
|
</Main>
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
### Props
|
||||||
|
|
||||||
|
<ArgsTable of={NoContent} />
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import EmptyStateDocument from '@strapi/icons/EmptyStateDocument';
|
||||||
|
import { EmptyStateLayout } from '@strapi/parts/EmptyStateLayout';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
const NoContent = ({ content, ...rest }) => {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EmptyStateLayout
|
||||||
|
icon={<EmptyStateDocument width="10rem" />}
|
||||||
|
{...rest}
|
||||||
|
content={formatMessage(
|
||||||
|
{ id: content.id, defaultMessage: content.defaultMessage },
|
||||||
|
content.values
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
NoContent.defaultProps = {
|
||||||
|
content: {
|
||||||
|
id: 'app.components.EmptyStateLayout.content-document',
|
||||||
|
defaultMessage: "You don't have any content yet...",
|
||||||
|
values: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
NoContent.propTypes = {
|
||||||
|
content: PropTypes.shape({
|
||||||
|
id: PropTypes.string,
|
||||||
|
defaultMessage: PropTypes.string,
|
||||||
|
values: PropTypes.object,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NoContent;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
<!--- EmptyStateLayout.stories.mdx --->
|
||||||
|
|
||||||
|
import { Meta, ArgsTable, Canvas, Story } from '@storybook/addon-docs';
|
||||||
|
import { Main, Row, Button } from '@strapi/parts';
|
||||||
|
import NoMedia from './index';
|
||||||
|
|
||||||
|
<Meta title="components/NoMedia" />
|
||||||
|
|
||||||
|
# NoMedia
|
||||||
|
|
||||||
|
This component is used to display an empty state.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story name="base">
|
||||||
|
<Main>
|
||||||
|
<NoMedia content="There's no media" action={<Button>Add a media</Button>} />
|
||||||
|
</Main>
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
### Props
|
||||||
|
|
||||||
|
<ArgsTable of={NoMedia} />
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import EmptyStatePicture from '@strapi/icons/EmptyStatePicture';
|
||||||
|
import { EmptyStateLayout } from '@strapi/parts/EmptyStateLayout';
|
||||||
|
|
||||||
|
const NoMedia = props => {
|
||||||
|
return <EmptyStateLayout icon={<EmptyStatePicture width="10rem" />} {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NoMedia;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
<!--- EmptyStateLayout.stories.mdx --->
|
||||||
|
|
||||||
|
import { Meta, ArgsTable, Canvas, Story } from '@storybook/addon-docs';
|
||||||
|
import { Main, Row } from '@strapi/parts';
|
||||||
|
import NoPermissions from './index';
|
||||||
|
|
||||||
|
<Meta title="components/NoPermissions" />
|
||||||
|
|
||||||
|
# NoPermissions
|
||||||
|
|
||||||
|
This component is used to display an empty state.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story name="base">
|
||||||
|
<Main>
|
||||||
|
<NoPermissions />
|
||||||
|
</Main>
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
### Props
|
||||||
|
|
||||||
|
<ArgsTable of={NoPermissions} />
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
import EmptyStatePermissions from '@strapi/icons/EmptyStatePermissions';
|
||||||
|
import { EmptyStateLayout } from '@strapi/parts/EmptyStateLayout';
|
||||||
|
|
||||||
|
const NoPermissions = ({ action }) => {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EmptyStateLayout
|
||||||
|
icon={<EmptyStatePermissions width="10rem" />}
|
||||||
|
content={formatMessage({
|
||||||
|
id: 'app.components.EmptyStateLayout.content-permissions',
|
||||||
|
defaultMessage: "You don't have the permissions to access that content",
|
||||||
|
})}
|
||||||
|
action={action}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
NoPermissions.defaultProps = {
|
||||||
|
action: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
NoPermissions.propTypes = {
|
||||||
|
action: PropTypes.node,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NoPermissions;
|
||||||
@ -183,6 +183,9 @@ export { default as ConfirmDialog } from './components/ConfirmDialog';
|
|||||||
export { default as ContentBox } from './components/ContentBox';
|
export { default as ContentBox } from './components/ContentBox';
|
||||||
export { default as CustomContentLayout } from './components/CustomContentLayout';
|
export { default as CustomContentLayout } from './components/CustomContentLayout';
|
||||||
export { default as EmptyStateLayout } from './components/EmptyStateLayout';
|
export { default as EmptyStateLayout } from './components/EmptyStateLayout';
|
||||||
|
export { default as NoContent } from './components/NoContent';
|
||||||
|
export { default as NoMedia } from './components/NoMedia';
|
||||||
|
export { default as NoPermissions } from './components/NoPermissions';
|
||||||
export { default as EmptyBodyTable } from './components/EmptyBodyTable';
|
export { default as EmptyBodyTable } from './components/EmptyBodyTable';
|
||||||
export { default as GenericInput } from './components/GenericInput';
|
export { default as GenericInput } from './components/GenericInput';
|
||||||
export * from './components/InjectionZone';
|
export * from './components/InjectionZone';
|
||||||
|
|||||||
@ -0,0 +1,74 @@
|
|||||||
|
<!--- EmptyStateLayout.stories.mdx --->
|
||||||
|
|
||||||
|
import { Meta, ArgsTable, Canvas, Story } from '@storybook/addon-docs';
|
||||||
|
import { Main, Layout, HeaderLayout, Button, ActionLayout, ContentLayout,Box } from '@strapi/parts';
|
||||||
|
import AddIcon from '@strapi/icons/AddIcon'
|
||||||
|
import EditIcon from '@strapi/icons/EditIcon'
|
||||||
|
import LoadingIndicatorPage from '../../components/LoadingIndicatorPage';
|
||||||
|
import NoContent from '../../components/NoContent'
|
||||||
|
import NoPermissions from '../../components/NoPermissions'
|
||||||
|
|
||||||
|
<Meta title="templates/PageTemplate" />
|
||||||
|
|
||||||
|
# PageTemplate
|
||||||
|
|
||||||
|
This component is used to display an empty state.
|
||||||
|
|
||||||
|
## Imports
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { Main } from '@strapi/parts/Main';
|
||||||
|
import { ActionLayout, ContentLayout, HeaderLayout, Layout } from '@strapi/parts/Layout';
|
||||||
|
import { Button } from '@strapi/parts/Button';
|
||||||
|
import { Box } from '@strapi/parts/Box';
|
||||||
|
import { LoadingIndicatorPage, NoContent, NoPermissions } from '@strapi/helper-plugin';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story name="base">
|
||||||
|
{() => {
|
||||||
|
const canRead = false;
|
||||||
|
const isLoading = true;
|
||||||
|
const data = [];
|
||||||
|
return (
|
||||||
|
<Box background="neutral100">
|
||||||
|
<Layout>
|
||||||
|
<Main labelledBy="title" aria-busy={isLoading}>
|
||||||
|
<HeaderLayout
|
||||||
|
id="title"
|
||||||
|
primaryAction={<Button startIcon={<AddIcon />}>Add an entry</Button>}
|
||||||
|
secondaryAction={
|
||||||
|
<Button variant="tertiary" startIcon={<EditIcon />}>
|
||||||
|
Edit
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
title="Other CT"
|
||||||
|
subtitle="36 entries found"
|
||||||
|
/>
|
||||||
|
<ActionLayout
|
||||||
|
startActions={
|
||||||
|
<>
|
||||||
|
<Button variant="tertiary">Search</Button>
|
||||||
|
<Button variant="tertiary">Filter</Button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
endActions={
|
||||||
|
<>
|
||||||
|
<Button variant="tertiary">Settings</Button>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<ContentLayout>
|
||||||
|
{!canRead && <NoPermissions />}
|
||||||
|
{(canRead && data && data.length === 0) && <NoContent content="No content available" action={<Button>Add content</Button>}/>}
|
||||||
|
{isLoading && <LoadingIndicatorPage />}
|
||||||
|
</ContentLayout>
|
||||||
|
</Main>
|
||||||
|
</Layout>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
@ -14,6 +14,7 @@ import {
|
|||||||
Th,
|
Th,
|
||||||
TableLabel,
|
TableLabel,
|
||||||
useNotifyAT,
|
useNotifyAT,
|
||||||
|
ContentLayout,
|
||||||
} from '@strapi/parts';
|
} from '@strapi/parts';
|
||||||
|
|
||||||
import { AddIcon, EditIcon } from '@strapi/icons';
|
import { AddIcon, EditIcon } from '@strapi/icons';
|
||||||
@ -23,8 +24,9 @@ import {
|
|||||||
SettingsPageTitle,
|
SettingsPageTitle,
|
||||||
CheckPermissions,
|
CheckPermissions,
|
||||||
useNotification,
|
useNotification,
|
||||||
CustomContentLayout,
|
|
||||||
useRBAC,
|
useRBAC,
|
||||||
|
NoPermissions,
|
||||||
|
LoadingIndicatorPage,
|
||||||
} from '@strapi/helper-plugin';
|
} from '@strapi/helper-plugin';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
@ -59,7 +61,10 @@ const RoleListPage = () => {
|
|||||||
isLoading: isLoadingForData,
|
isLoading: isLoadingForData,
|
||||||
data: { roles },
|
data: { roles },
|
||||||
isFetching,
|
isFetching,
|
||||||
} = useQuery('get-roles', () => fetchData(toggleNotification, notifyStatus), { initialData: {} });
|
} = useQuery('get-roles', () => fetchData(toggleNotification, notifyStatus), {
|
||||||
|
initialData: {},
|
||||||
|
enabled: canRead,
|
||||||
|
});
|
||||||
|
|
||||||
const isLoading = isLoadingForData || isFetching;
|
const isLoading = isLoadingForData || isFetching;
|
||||||
|
|
||||||
@ -73,7 +78,7 @@ const RoleListPage = () => {
|
|||||||
defaultMessage: 'Roles',
|
defaultMessage: 'Roles',
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleClickEdit = (id) => {
|
const handleClickEdit = id => {
|
||||||
push(`/settings/${pluginId}/roles/${id}`);
|
push(`/settings/${pluginId}/roles/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -104,70 +109,74 @@ const RoleListPage = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CustomContentLayout
|
<ContentLayout
|
||||||
canRead={canRead}
|
canRead={canRead}
|
||||||
shouldShowEmptyState={roles && !roles.length}
|
shouldShowEmptyState={roles && !roles.length}
|
||||||
isLoading={isLoading || isLoadingForPermissions}
|
isLoading={isLoading || isLoadingForPermissions}
|
||||||
>
|
>
|
||||||
<Table colCount={4} rowCount={roles && roles.length + 1}>
|
{!canRead && <NoPermissions />}
|
||||||
<Thead>
|
{(isLoading || isLoadingForPermissions) && <LoadingIndicatorPage />}
|
||||||
<Tr>
|
{canRead && roles && roles.length && (
|
||||||
<Th>
|
<Table colCount={4} rowCount={roles && roles.length + 1}>
|
||||||
<TableLabel>
|
<Thead>
|
||||||
{formatMessage({ id: getTrad('Roles.name'), defaultMessage: 'Name' })}
|
<Tr>
|
||||||
</TableLabel>
|
<Th>
|
||||||
</Th>
|
<TableLabel>
|
||||||
<Th>
|
{formatMessage({ id: getTrad('Roles.name'), defaultMessage: 'Name' })}
|
||||||
<TableLabel>
|
</TableLabel>
|
||||||
{formatMessage({
|
</Th>
|
||||||
id: getTrad('Roles.description'),
|
<Th>
|
||||||
defaultMessage: 'Description',
|
<TableLabel>
|
||||||
})}
|
{formatMessage({
|
||||||
</TableLabel>
|
id: getTrad('Roles.description'),
|
||||||
</Th>
|
defaultMessage: 'Description',
|
||||||
<Th>
|
})}
|
||||||
<TableLabel>
|
</TableLabel>
|
||||||
{formatMessage({
|
</Th>
|
||||||
id: getTrad('Roles.users'),
|
<Th>
|
||||||
defaultMessage: 'Users',
|
<TableLabel>
|
||||||
})}
|
{formatMessage({
|
||||||
</TableLabel>
|
id: getTrad('Roles.users'),
|
||||||
</Th>
|
defaultMessage: 'Users',
|
||||||
</Tr>
|
})}
|
||||||
</Thead>
|
</TableLabel>
|
||||||
<Tbody>
|
</Th>
|
||||||
{roles &&
|
</Tr>
|
||||||
roles.map((role) => (
|
</Thead>
|
||||||
<Tr key={role.name}>
|
<Tbody>
|
||||||
<Td width="20%">
|
{roles &&
|
||||||
<Text>{role.name}</Text>
|
roles.map(role => (
|
||||||
</Td>
|
<Tr key={role.name}>
|
||||||
<Td width="50%">
|
<Td width="20%">
|
||||||
<Text>{role.description}</Text>
|
<Text>{role.name}</Text>
|
||||||
</Td>
|
</Td>
|
||||||
<Td width="30%">
|
<Td width="50%">
|
||||||
<Text>
|
<Text>{role.description}</Text>
|
||||||
{`${role.nb_users} ${formatMessage({
|
</Td>
|
||||||
id: getTrad('Roles.users'),
|
<Td width="30%">
|
||||||
defaultMessage: 'users',
|
<Text>
|
||||||
}).toLowerCase()}`}
|
{`${role.nb_users} ${formatMessage({
|
||||||
</Text>
|
id: getTrad('Roles.users'),
|
||||||
</Td>
|
defaultMessage: 'users',
|
||||||
<Td>
|
}).toLowerCase()}`}
|
||||||
<CheckPermissions permissions={permissions.updateRole}>
|
</Text>
|
||||||
<IconButton
|
</Td>
|
||||||
onClick={() => handleClickEdit(role.id)}
|
<Td>
|
||||||
noBorder
|
<CheckPermissions permissions={permissions.updateRole}>
|
||||||
icon={<EditIcon />}
|
<IconButton
|
||||||
label="Edit"
|
onClick={() => handleClickEdit(role.id)}
|
||||||
/>
|
noBorder
|
||||||
</CheckPermissions>
|
icon={<EditIcon />}
|
||||||
</Td>
|
label="Edit"
|
||||||
</Tr>
|
/>
|
||||||
))}
|
</CheckPermissions>
|
||||||
</Tbody>
|
</Td>
|
||||||
</Table>
|
</Tr>
|
||||||
</CustomContentLayout>
|
))}
|
||||||
|
</Tbody>
|
||||||
|
</Table>
|
||||||
|
)}
|
||||||
|
</ContentLayout>
|
||||||
</Main>
|
</Main>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -91,6 +91,11 @@ describe('Admin | containers | RoleListPage', () => {
|
|||||||
padding-left: 56px;
|
padding-left: 56px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.c10 {
|
||||||
|
padding-right: 56px;
|
||||||
|
padding-left: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
.c5 {
|
.c5 {
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
display: -webkit-flex;
|
display: -webkit-flex;
|
||||||
@ -136,11 +141,6 @@ describe('Admin | containers | RoleListPage', () => {
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c10 {
|
|
||||||
padding-right: 56px;
|
|
||||||
padding-left: 56px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c13 {
|
.c13 {
|
||||||
border: 0;
|
border: 0;
|
||||||
-webkit-clip: rect(0 0 0 0);
|
-webkit-clip: rect(0 0 0 0);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user