Merge branch 'master' into features/api-token-v2

This commit is contained in:
Bassel Kanso 2022-08-05 09:55:17 +03:00
commit 52c0a74418
9 changed files with 157 additions and 90 deletions

View File

@ -108,10 +108,21 @@ export const UploadingAssetCard = ({
</Card>
{error ? (
<Typography variant="pi" fontWeight="bold" textColor="danger600">
{formatMessage({
id: getTrad(`apiError.${error.response.data.error.message}`),
defaultMessage: error.response.data.error.message,
})}
{formatMessage(
error?.response?.data?.error?.message
? {
id: getTrad(`apiError.${error.response.data.error.message}`),
defaultMessage: error.response.data.error.message,
/* See issue: https://github.com/strapi/strapi/issues/13867
A proxy might return an error, before the request reaches Strapi
and therefore we need to handle errors gracefully.
*/
}
: {
id: getTrad('upload.generic-error'),
defaultMessage: 'An error occured while uploading the file.',
}
)}
</Typography>
) : (
undefined

View File

@ -6,7 +6,6 @@ import { stringify } from 'qs';
import {
LoadingIndicatorPage,
useFocusWhenNavigate,
NoPermissions,
AnErrorOccurred,
SearchURLQuery,
useSelectionState,
@ -15,8 +14,6 @@ import {
} from '@strapi/helper-plugin';
import { Layout, ContentLayout, ActionLayout } from '@strapi/design-system/Layout';
import { Main } from '@strapi/design-system/Main';
import { Button } from '@strapi/design-system/Button';
import Plus from '@strapi/icons/Plus';
import { Box } from '@strapi/design-system/Box';
import { Divider } from '@strapi/design-system/Divider';
import { BaseCheckbox } from '@strapi/design-system/BaseCheckbox';
@ -38,7 +35,6 @@ import { getTrad, containsAssetFilter } from '../../utils';
import { PaginationFooter } from '../../components/PaginationFooter';
import { useMediaLibraryPermissions } from '../../hooks/useMediaLibraryPermissions';
import { useFolder } from '../../hooks/useFolder';
import { EmptyAssets } from '../../components/EmptyAssets';
import { BulkActions } from './components/BulkActions';
import {
FolderCard,
@ -48,6 +44,7 @@ import {
} from '../../components/FolderCard';
import { Filters } from './components/Filters';
import { Header } from './components/Header';
import { EmptyOrNoPermissions } from './components/EmptyOrNoPermissions';
const BoxWithHeight = styled(Box)`
height: ${32 / 16}rem;
@ -227,43 +224,15 @@ export const MediaLibrary = () => {
{(assetsError || foldersError) && <AnErrorOccurred />}
{folderCount === 0 && assetCount === 0 && (
<EmptyAssets
action={
canCreate &&
!isFiltering && (
<Button
variant="secondary"
startIcon={<Plus />}
onClick={toggleUploadAssetDialog}
>
{formatMessage({
id: getTrad('header.actions.add-assets'),
defaultMessage: 'Add new assets',
})}
</Button>
)
}
content={
// eslint-disable-next-line no-nested-ternary
isFiltering
? formatMessage({
id: getTrad('list.assets-empty.title-withSearch'),
defaultMessage: 'There are no elements with the applied filters',
})
: canCreate
? formatMessage({
id: getTrad('list.assets.empty'),
defaultMessage: 'Upload your first assets...',
})
: formatMessage({
id: getTrad('list.assets.empty.no-permissions'),
defaultMessage: 'The asset list is empty',
})
}
<EmptyOrNoPermissions
canCreate={canCreate}
canRead={canRead}
isFiltering={isFiltering}
onActionClick={toggleUploadAssetDialog}
/>
)}
{canRead ? (
{canRead && (
<>
{folderCount > 0 && (
<FolderList
@ -387,8 +356,6 @@ export const MediaLibrary = () => {
</>
)}
</>
) : (
<NoPermissions />
)}
</ContentLayout>
</Main>

View File

@ -0,0 +1,71 @@
import PropTypes from 'prop-types';
import React from 'react';
import { useIntl } from 'react-intl';
import { Button } from '@strapi/design-system/Button';
import EmptyPermissions from '@strapi/icons/EmptyPermissions';
import Plus from '@strapi/icons/Plus';
import { EmptyAssets } from '../../../components/EmptyAssets';
import { getTrad } from '../../../utils';
const getContentIntlMessage = ({ isFiltering, canCreate, canRead }) => {
if (isFiltering) {
return {
id: 'list.assets-empty.title-withSearch',
defaultMessage: 'There are no elements with the applied filters',
};
}
if (canRead) {
if (canCreate) {
return {
id: 'list.assets.empty-upload',
defaultMessage: 'Upload your first assets...',
};
}
return {
id: 'list.assets.empty',
defaultMessage: 'Media Library is empty',
};
}
return {
id: 'header.actions.no-permissions',
defaultMessage: 'No permissions to view',
};
};
export const EmptyOrNoPermissions = ({ canCreate, isFiltering, canRead, onActionClick }) => {
const { formatMessage } = useIntl();
const content = getContentIntlMessage({ isFiltering, canCreate, canRead });
return (
<EmptyAssets
icon={!canRead ? EmptyPermissions : null}
action={
canCreate &&
!isFiltering && (
<Button variant="secondary" startIcon={<Plus />} onClick={onActionClick}>
{formatMessage({
id: getTrad('header.actions.add-assets'),
defaultMessage: 'Add new assets',
})}
</Button>
)
}
content={formatMessage({
...content,
id: getTrad(content.id),
})}
/>
);
};
EmptyOrNoPermissions.propTypes = {
canCreate: PropTypes.bool.isRequired,
canRead: PropTypes.bool.isRequired,
isFiltering: PropTypes.bool.isRequired,
onActionClick: PropTypes.func.isRequired,
};

View File

@ -0,0 +1,53 @@
import React from 'react';
import { ThemeProvider, lightTheme } from '@strapi/design-system';
import { render } from '@testing-library/react';
import { IntlProvider } from 'react-intl';
import { EmptyOrNoPermissions } from '../EmptyOrNoPermissions';
const setup = props =>
render(
<ThemeProvider theme={lightTheme}>
<IntlProvider locale="en" messages={{}}>
<EmptyOrNoPermissions
onActionClick={() => {}}
isFiltering={false}
canCreate
canRead
{...props}
/>
</IntlProvider>
</ThemeProvider>
);
describe('EmptyOrNoPermissions', () => {
test('isFiltering', () => {
const { queryByText } = setup({ isFiltering: true });
expect(queryByText('There are no elements with the applied filters')).toBeInTheDocument();
});
test('canCreate', () => {
const { queryByText } = setup({});
expect(queryByText('Add new assets')).toBeInTheDocument();
});
test('isFiltering and canCreate', () => {
const { queryByText } = setup({ isFiltering: true });
expect(queryByText('Add new assets')).not.toBeInTheDocument();
});
test('canRead and not canCreate', () => {
const { queryByText } = setup({ canCreate: false });
expect(queryByText('Media Library is empty')).toBeInTheDocument();
});
test('not canRead', () => {
const { queryByText } = setup({ canRead: false });
expect(queryByText('No permissions to view')).toBeInTheDocument();
});
});

View File

@ -500,26 +500,6 @@ describe('Media library homepage', () => {
expect(screen.queryByText('Upload your first assets...')).toBeInTheDocument();
});
it('does not display empty assets action, if there are no assets and the user does not have create permissions', () => {
useMediaLibraryPermissions.mockReturnValueOnce({
isLoading: false,
canCreate: false,
canRead: false,
});
useAssets.mockReturnValueOnce({
isLoading: false,
error: null,
data: {
pagination: FIXTURE_ASSET_PAGINATION,
results: FIXTURE_ASSETS,
},
});
renderML();
expect(screen.queryByText('header.actions.add-assets')).not.toBeInTheDocument();
});
it('does not display empty assets action, if there are no assets, no folders and the user is currently filtering', () => {
useQueryParams.mockReturnValueOnce([{ rawQuery: '', query: { filters: 'true' } }, jest.fn()]);
useAssets.mockReturnValueOnce({

View File

@ -1,5 +1,6 @@
{
"apiError.FileTooBig": "The uploaded file exceeds the maximum allowed asset size.",
"upload.generic-error": "An error occurred while uploading the file.",
"bulk.select.label": "Select all assets",
"button.next": "Next",
"checkControl.crop-duplicate": "Duplicate & crop the asset",
@ -43,8 +44,9 @@
"list.assets-empty.subtitle": "Add one to the list.",
"list.assets-empty.title": "There are no assets yet",
"list.assets-empty.title-withSearch": "There are no elements with the applied filters",
"list.assets.empty": "Upload your first assets...",
"list.assets.empty.no-permissions": "The asset list is empty.",
"list.assets.empty": "Media Library is empty",
"list.assets.empty-upload": "Upload your first assets...",
"list.assets.empty.no-permissions": "No permissions to view",
"list.assets.loading-asset": "Loading the preview for the media: {path}",
"list.assets.not-supported-content": "No preview available",
"list.assets.preview-asset": "Preview for the video at path {path}",

View File

@ -27,7 +27,6 @@
"test:front:watch:ce": "cross-env IS_EE=false jest --config ./jest.config.front.js --watchAll"
},
"dependencies": {
"@apollo/federation": "^0.28.0",
"@graphql-tools/schema": "8.1.2",
"@graphql-tools/utils": "^8.9.0",
"@strapi/utils": "4.3.2",

View File

@ -37,7 +37,7 @@
"test": "echo \"no tests yet\""
},
"dependencies": {
"aws-sdk": "2.1186.0",
"aws-sdk": "2.1188.0",
"lodash": "4.17.21"
},
"engines": {

View File

@ -40,15 +40,6 @@
dependencies:
"@jridgewell/trace-mapping" "^0.3.0"
"@apollo/federation@^0.28.0":
version "0.28.0"
resolved "https://registry.yarnpkg.com/@apollo/federation/-/federation-0.28.0.tgz#bbfcde3f327b3ec65dcfd98c6f52d6623a38b251"
integrity sha512-M5Dp0XJhuxEOzYjPWWK5VtIqEI1IFRioh1+XHrls90UC8R+b6VXa0UxMO/zfKv00APr4gBODMcfRe5w97NSruw==
dependencies:
apollo-graphql "^0.9.3"
apollo-server-types "^3.0.2"
lodash.xorby "^4.7.0"
"@apollo/protobufjs@1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@apollo/protobufjs/-/protobufjs-1.2.2.tgz#4bd92cd7701ccaef6d517cdb75af2755f049f87c"
@ -8632,7 +8623,7 @@ apollo-datasource@^3.3.2:
"@apollo/utils.keyvaluecache" "^1.0.1"
apollo-server-env "^4.2.1"
apollo-graphql@^0.9.0, apollo-graphql@^0.9.3:
apollo-graphql@^0.9.0:
version "0.9.6"
resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.9.6.tgz#756312a92685b0547f82cceb04f5b2d6e9f0df5c"
integrity sha512-CrqJxZwfu/U5x0bYYPPluwu1G+oC3jjKFK/EVn9CDcpi4+yD9rAYko/h1iUB5A6VRQhA4Boluc7QexMYQ2tCng==
@ -8760,7 +8751,7 @@ apollo-server-plugin-base@^3.6.2:
dependencies:
apollo-server-types "^3.6.2"
apollo-server-types@^3.0.2, apollo-server-types@^3.1.1, apollo-server-types@^3.5.2, apollo-server-types@^3.6.2:
apollo-server-types@^3.1.1, apollo-server-types@^3.5.2, apollo-server-types@^3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-3.6.2.tgz#34bb0c335fcce3057cbdf72b3b63da182de6fc84"
integrity sha512-9Z54S7NB+qW1VV+kmiqwU2Q6jxWfX89HlSGCGOo3zrkrperh85LrzABgN9S92+qyeHYd72noMDg2aI039sF3dg==
@ -9114,10 +9105,10 @@ available-typed-arrays@^1.0.5:
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
aws-sdk@2.1186.0, aws-sdk@^2.382.0:
version "2.1186.0"
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1186.0.tgz#f08fc5f1f53defa1fff83177621947dc0ca8d29b"
integrity sha512-3yDWwNWgbSH9tRVyan0PlRU938Po9QH+06XHwRNwAa/6bixYl4L48c6YgpfxBpwl0IvcCCTivD7ZqshndwishQ==
aws-sdk@2.1188.0, aws-sdk@^2.382.0:
version "2.1188.0"
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1188.0.tgz#94b710948ef2924093a8d6fe42443a792385afa2"
integrity sha512-4KXwjRjbCzU1luTOeH+ded92H51I4UuHaZzx2EI+JA0II1+q48heTxFlFd7yp7jGz9UwjPb6k12Jv1W3r0JWxA==
dependencies:
buffer "4.9.2"
events "1.1.1"
@ -18137,11 +18128,6 @@ lodash.uniq@4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
lodash.xorby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.xorby/-/lodash.xorby-4.7.0.tgz#9c19a6f9f063a6eb53dd03c1b6871799801463d7"
integrity sha1-nBmm+fBjputT3QPBtocXmYAUY9c=
lodash@4.17.21, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@ -20837,8 +20823,6 @@ path-case@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5"
integrity sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=
dependencies:
no-case "^2.2.0"
path-dirname@^1.0.0:
version "1.0.2"