refactor isSelectable usage + fix grid view selection

This commit is contained in:
Julie Plantey 2022-11-24 19:47:56 +01:00
parent 36cf9ea857
commit 1824d5f8be
12 changed files with 284 additions and 235 deletions

View File

@ -6,34 +6,21 @@ import { VideoAssetCard } from './VideoAssetCard';
import { DocAssetCard } from './DocAssetCard';
import { AudioAssetCard } from './AudioAssetCard';
import { AssetType, AssetDefinition } from '../../constants';
import { createAssetUrl, toSingularTypes } from '../../utils';
import { createAssetUrl } from '../../utils';
export const AssetCard = ({
allowedTypes,
asset,
isSelected,
onSelect,
onEdit,
onRemove,
size,
local,
}) => {
const singularTypes = toSingularTypes(allowedTypes);
const fileType = asset.mime.split('/')[0];
export const AssetCard = ({ asset, isSelected, onSelect, onEdit, onRemove, size, local }) => {
const handleSelect = onSelect ? () => onSelect(asset) : undefined;
const canSelectAsset =
singularTypes.includes(fileType) ||
(singularTypes.includes('file') && !['video', 'image', 'audio'].includes(fileType));
const commonAssetCardProps = {
id: asset.id,
isSelectable: asset.isSelectable,
extension: getFileExtension(asset.ext),
key: asset.id,
name: asset.name,
url: local ? asset.url : createAssetUrl(asset, true),
mime: asset.mime,
onEdit: onEdit ? () => onEdit(asset) : undefined,
onSelect: !canSelectAsset && !isSelected ? undefined : handleSelect,
onSelect: handleSelect,
onRemove: onRemove ? () => onRemove(asset) : undefined,
selected: isSelected,
size,
@ -63,7 +50,6 @@ export const AssetCard = ({
};
AssetCard.defaultProps = {
allowedTypes: ['images', 'files', 'videos', 'audios'],
isSelected: false,
// Determine if the asset is loaded locally or from a remote resource
local: false,
@ -74,7 +60,6 @@ AssetCard.defaultProps = {
};
AssetCard.propTypes = {
allowedTypes: PropTypes.array,
asset: AssetDefinition.isRequired,
local: PropTypes.bool,
onSelect: PropTypes.func,

View File

@ -44,12 +44,13 @@ const CardContainer = styled(Card)`
export const AssetCardBase = ({
children,
name,
extension,
selected,
isSelectable,
name,
onSelect,
onRemove,
onEdit,
selected,
subtitle,
variant,
}) => {
@ -76,7 +77,7 @@ export const AssetCardBase = ({
return (
<CardContainer role="button" height="100%" tabIndex={-1} onClick={handleClick}>
<CardHeader>
{onSelect && (
{isSelectable && (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<div onClick={handlePropagationClick}>
<CardCheckbox value={selected} onValueChange={onSelect} />
@ -129,10 +130,11 @@ export const AssetCardBase = ({
AssetCardBase.defaultProps = {
children: undefined,
selected: false,
isSelectable: true,
onEdit: undefined,
onSelect: undefined,
onRemove: undefined,
selected: false,
subtitle: '',
variant: 'Image',
};
@ -140,6 +142,7 @@ AssetCardBase.defaultProps = {
AssetCardBase.propTypes = {
children: PropTypes.node,
extension: PropTypes.string.isRequired,
isSelectable: PropTypes.bool,
name: PropTypes.string.isRequired,
onEdit: PropTypes.func,
onSelect: PropTypes.func,

View File

@ -25,7 +25,7 @@ import {
localStorageKeys,
} from '../../../constants';
import getTrad from '../../../utils/getTrad';
import { getBreadcrumbDataCM } from '../../../utils';
import { getBreadcrumbDataCM, toSingularTypes } from '../../../utils';
import getAllowedFiles from '../../../utils/getAllowedFiles';
import { AssetGridList } from '../../AssetGridList';
import { TableList } from '../../TableList';
@ -39,6 +39,7 @@ import { Filters } from './Filters';
import PaginationFooter from './PaginationFooter';
import PageSize from './PageSize';
import SearchAsset from './SearchAsset';
import { isSelectable } from './utils/isSelectable';
const StartBlockActions = styled(Flex)`
& > * + * {
@ -65,7 +66,7 @@ const ActionContainer = styled(Box)`
export const BrowseStep = ({
allowedTypes,
assets,
assets: rawAssets,
canCreate,
canRead,
folders,
@ -96,6 +97,13 @@ export const BrowseStep = ({
}
);
const singularTypes = toSingularTypes(allowedTypes);
const assets = rawAssets.map((asset) => {
const fileType = asset?.mime?.split('/')?.[0];
return { ...asset, isSelectable: isSelectable(singularTypes, fileType) };
});
const breadcrumbs = !isCurrentFolderLoading && getBreadcrumbDataCM(currentFolder);
const allAllowedAsset = getAllowedFiles(allowedTypes, assets);
@ -249,10 +257,7 @@ export const BrowseStep = ({
// TODO: remove when fixed on DS side
// when number of rows in Table changes, the keyboard tab from a row to another
// is not working for 1st and last column
[
...folders.map((folder) => ({ ...folder, type: 'folder' })),
...assets.map((asset) => ({ ...asset, type: 'asset' })),
]
[...folders.map((folder) => ({ ...folder, type: 'folder' })), ...assets]
}
selected={selectedAssets}
shouldDisableBulkSelect={!multiple}

View File

@ -0,0 +1,3 @@
export const isSelectable = (allowedTypes, fileType) =>
allowedTypes.includes(fileType) ||
(allowedTypes.includes('file') && !['video', 'image', 'audio'].includes(fileType));

View File

@ -0,0 +1,19 @@
import { isSelectable } from '../isSelectable';
describe('TableList | isSelectable', () => {
it('should return true if asset is an allowed file type', () => {
expect(isSelectable(['image', 'file', 'video', 'audio'], 'image')).toEqual(true);
});
it('should return true if asset type is not contained in allowed types array but file type is contained', () => {
expect(isSelectable(['video', 'audio', 'file'], 'pdf')).toEqual(true);
});
it('should return false if asset type is not contained in allowed types array and file type is image, video or audio', () => {
expect(isSelectable(['video', 'audio', 'file'], 'image')).toEqual(false);
expect(isSelectable(['image', 'audio', 'file'], 'video')).toEqual(false);
expect(isSelectable(['image', 'video', 'file'], 'audio')).toEqual(false);
});
});

View File

@ -11,14 +11,10 @@ import Pencil from '@strapi/icons/Pencil';
import Eye from '@strapi/icons/Eye';
import { CellContent } from './CellContent';
import { isSelectable } from './utils/isSelectable';
import { AssetDefinition, FolderDefinition, tableHeaders as cells } from '../../constants';
import { getTrad, toSingularTypes } from '../../utils';
import { getTrad } from '../../utils';
export const TableRows = ({
allowedTypes,
canUpdate,
isFolderSelectionAllowed,
onChangeFolder,
onEditAsset,
onEditFolder,
@ -36,14 +32,13 @@ export const TableRows = ({
}
};
const singularTypes = toSingularTypes(allowedTypes);
return (
<Tbody>
{rows.map((element) => {
const {
alternativeText,
id,
isSelectable,
name,
ext,
url,
@ -53,10 +48,6 @@ export const TableRows = ({
type: elementType,
} = element;
const fileType = mime?.split('/')?.[0];
const canBeSelected =
isSelectable(singularTypes, elementType, fileType, isFolderSelectionAllowed) && canUpdate;
const isSelected = !!selected.find((currentRow) => currentRow.id === id);
return (
@ -76,7 +67,7 @@ export const TableRows = ({
},
{ name }
)}
disabled={!canBeSelected}
disabled={!isSelectable}
onValueChange={() => onSelectOne(element)}
checked={isSelected}
/>
@ -136,22 +127,16 @@ export const TableRows = ({
};
TableRows.defaultProps = {
allowedTypes: ['images', 'files', 'videos', 'audios'],
canUpdate: true,
onChangeFolder: null,
isFolderSelectionAllowed: true,
rows: [],
selected: [],
};
TableRows.propTypes = {
allowedTypes: PropTypes.arrayOf(PropTypes.string),
canUpdate: PropTypes.bool,
isFolderSelectionAllowed: PropTypes.bool,
rows: PropTypes.arrayOf(AssetDefinition, FolderDefinition),
onChangeFolder: PropTypes.func,
onEditAsset: PropTypes.func.isRequired,
onEditFolder: PropTypes.func.isRequired,
onSelectOne: PropTypes.func.isRequired,
rows: PropTypes.arrayOf(AssetDefinition, FolderDefinition),
selected: PropTypes.arrayOf(AssetDefinition, FolderDefinition),
};

View File

@ -15,9 +15,6 @@ import { TableRows } from './TableRows';
export const TableList = ({
assetCount,
isFolderSelectionAllowed,
allowedTypes,
canUpdate,
folderCount,
indeterminate,
onChangeSort,
@ -114,9 +111,6 @@ export const TableList = ({
</Tr>
</Thead>
<TableRows
isFolderSelectionAllowed={isFolderSelectionAllowed}
allowedTypes={allowedTypes}
canUpdate={canUpdate}
onChangeFolder={onChangeFolder}
onEditAsset={onEditAsset}
onEditFolder={onEditFolder}
@ -130,11 +124,8 @@ export const TableList = ({
TableList.defaultProps = {
assetCount: 0,
allowedTypes: ['images', 'files', 'videos', 'audios'],
canUpdate: true,
folderCount: 0,
indeterminate: false,
isFolderSelectionAllowed: true,
onChangeSort: null,
onChangeFolder: null,
onEditAsset: null,
@ -146,12 +137,9 @@ TableList.defaultProps = {
};
TableList.propTypes = {
allowedTypes: PropTypes.arrayOf(PropTypes.string),
assetCount: PropTypes.number,
canUpdate: PropTypes.bool,
folderCount: PropTypes.number,
indeterminate: PropTypes.bool,
isFolderSelectionAllowed: PropTypes.bool,
onChangeSort: PropTypes.func,
onChangeFolder: PropTypes.func,
onEditAsset: PropTypes.func,

View File

@ -1,13 +0,0 @@
export const isSelectable = (allowedTypes, elementType, fileType, isFolderSelectionAllowed) => {
let canSelectElement;
if (elementType === 'folder') {
canSelectElement = isFolderSelectionAllowed;
} else {
canSelectElement =
allowedTypes.includes(fileType) ||
(allowedTypes.includes('file') && !['video', 'image', 'audio'].includes(fileType));
}
return canSelectElement;
};

View File

@ -1,74 +0,0 @@
import { isSelectable } from '../isSelectable';
const ALLOWED_TYPES_FIXTURE = ['image', 'file', 'video', 'audio'];
const ELEMENT_TYPE_FIXTURE = 'asset';
const FILE_TYPE_FIXTURE = 'image';
const IS_FOLDER_SELECTION_ALLOWED_FIXTURE = true;
describe('TableList | isSelectable', () => {
it('should return true if asset is an allowed file type', () => {
expect(
isSelectable(
ALLOWED_TYPES_FIXTURE,
ELEMENT_TYPE_FIXTURE,
FILE_TYPE_FIXTURE,
IS_FOLDER_SELECTION_ALLOWED_FIXTURE
)
).toEqual(true);
});
it('should return true if asset type is not contained in allowed types array but file type is contained', () => {
expect(
isSelectable(
['video', 'audio', 'file'],
ELEMENT_TYPE_FIXTURE,
'pdf',
IS_FOLDER_SELECTION_ALLOWED_FIXTURE
)
).toEqual(true);
});
it('should return false if asset type is not contained in allowed types array and file type is image, video or audio', () => {
expect(
isSelectable(
['video', 'audio', 'file'],
ELEMENT_TYPE_FIXTURE,
'image',
IS_FOLDER_SELECTION_ALLOWED_FIXTURE
)
).toEqual(false);
expect(
isSelectable(
['image', 'audio', 'file'],
ELEMENT_TYPE_FIXTURE,
'video',
IS_FOLDER_SELECTION_ALLOWED_FIXTURE
)
).toEqual(false);
expect(
isSelectable(
['image', 'video', 'file'],
ELEMENT_TYPE_FIXTURE,
'audio',
IS_FOLDER_SELECTION_ALLOWED_FIXTURE
)
).toEqual(false);
});
it('should return true if folder is allowed', () => {
expect(
isSelectable(
ALLOWED_TYPES_FIXTURE,
'folder',
FILE_TYPE_FIXTURE,
IS_FOLDER_SELECTION_ALLOWED_FIXTURE
)
).toEqual(true);
});
it('should return false if folder is not allowed', () => {
expect(isSelectable(ALLOWED_TYPES_FIXTURE, 'folder', FILE_TYPE_FIXTURE, false)).toEqual(false);
});
});

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
.c52 {
.c55 {
border: 0;
-webkit-clip: rect(0 0 0 0);
clip: rect(0 0 0 0);
@ -48,33 +48,37 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
}
.c24 {
position: start;
}
.c29 {
position: end;
}
.c32 {
.c35 {
padding-top: 8px;
padding-right: 12px;
padding-bottom: 8px;
padding-left: 12px;
}
.c35 {
.c38 {
padding-top: 4px;
}
.c38 {
.c41 {
background: #f6f6f9;
padding: 4px;
border-radius: 4px;
min-width: 20px;
}
.c42 {
.c45 {
width: 100%;
height: 5.5rem;
}
.c46 {
.c49 {
background: #32324d;
color: #ffffff;
padding: 4px;
@ -145,7 +149,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
flex-direction: row;
}
.c33 {
.c36 {
-webkit-align-items: flex-start;
-webkit-box-align: flex-start;
-ms-flex-align: flex-start;
@ -159,7 +163,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
flex-direction: row;
}
.c39 {
.c42 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
@ -205,7 +209,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
color: #32324d;
}
.c41 {
.c44 {
font-weight: 600;
font-size: 0.6875rem;
line-height: 1.45;
@ -213,7 +217,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
color: #666687;
}
.c48 {
.c51 {
font-size: 0.75rem;
line-height: 1.33;
color: #ffffff;
@ -370,7 +374,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
fill: #ffffff;
}
.c51 {
.c54 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
@ -384,7 +388,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
background: #ffffff;
}
.c51 .c0 {
.c54 .c0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
@ -395,55 +399,123 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
align-items: center;
}
.c51 .c4 {
.c54 .c4 {
color: #ffffff;
}
.c51[aria-disabled='true'] {
.c54[aria-disabled='true'] {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c51[aria-disabled='true'] .c4 {
.c54[aria-disabled='true'] .c4 {
color: #666687;
}
.c51[aria-disabled='true'] svg > g,
.c51[aria-disabled='true'] svg path {
.c54[aria-disabled='true'] svg > g,
.c54[aria-disabled='true'] svg path {
fill: #666687;
}
.c51[aria-disabled='true']:active {
.c54[aria-disabled='true']:active {
border: 1px solid #dcdce4;
background: #eaeaef;
}
.c51[aria-disabled='true']:active .c4 {
.c54[aria-disabled='true']:active .c4 {
color: #666687;
}
.c51[aria-disabled='true']:active svg > g,
.c51[aria-disabled='true']:active svg path {
.c54[aria-disabled='true']:active svg > g,
.c54[aria-disabled='true']:active svg path {
fill: #666687;
}
.c51:hover {
.c54:hover {
background-color: #f6f6f9;
}
.c51:active {
.c54:active {
background-color: #eaeaef;
}
.c51 .c4 {
.c54 .c4 {
color: #32324d;
}
.c51 svg > g,
.c51 svg path {
.c54 svg > g,
.c54 svg path {
fill: #32324d;
}
.c28 {
margin: 0;
height: 18px;
min-width: 18px;
border-radius: 4px;
border: 1px solid #c0c0cf;
-webkit-appearance: none;
background-color: #ffffff;
cursor: pointer;
}
.c28:checked {
background-color: #4945ff;
border: 1px solid #4945ff;
}
.c28:checked:after {
content: '';
display: block;
position: relative;
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iOCIgdmlld0JveD0iMCAwIDEwIDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGgKICAgIGQ9Ik04LjU1MzIzIDAuMzk2OTczQzguNjMxMzUgMC4zMTYzNTUgOC43NjA1MSAwLjMxNTgxMSA4LjgzOTMxIDAuMzk1NzY4TDkuODYyNTYgMS40MzQwN0M5LjkzODkzIDEuNTExNTcgOS45MzkzNSAxLjYzNTkgOS44NjM0OSAxLjcxMzlMNC4wNjQwMSA3LjY3NzI0QzMuOTg1OSA3Ljc1NzU1IDMuODU3MDcgNy43NTgwNSAzLjc3ODM0IDcuNjc4MzRMMC4xMzg2NiAzLjk5MzMzQzAuMDYxNzc5OCAzLjkxNTQ5IDAuMDYxNzEwMiAzLjc5MDMyIDAuMTM4NTA0IDMuNzEyNEwxLjE2MjEzIDIuNjczNzJDMS4yNDAzOCAyLjU5NDMyIDEuMzY4NDMgMi41OTQyMiAxLjQ0NjggMi42NzM0OEwzLjkyMTc0IDUuMTc2NDdMOC41NTMyMyAwLjM5Njk3M1oiCiAgICBmaWxsPSJ3aGl0ZSIKICAvPgo8L3N2Zz4=) no-repeat no-repeat center center;
width: 10px;
height: 10px;
left: 50%;
top: 50%;
-webkit-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
.c28:checked:disabled:after {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iOCIgdmlld0JveD0iMCAwIDEwIDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGgKICAgIGQ9Ik04LjU1MzIzIDAuMzk2OTczQzguNjMxMzUgMC4zMTYzNTUgOC43NjA1MSAwLjMxNTgxMSA4LjgzOTMxIDAuMzk1NzY4TDkuODYyNTYgMS40MzQwN0M5LjkzODkzIDEuNTExNTcgOS45MzkzNSAxLjYzNTkgOS44NjM0OSAxLjcxMzlMNC4wNjQwMSA3LjY3NzI0QzMuOTg1OSA3Ljc1NzU1IDMuODU3MDcgNy43NTgwNSAzLjc3ODM0IDcuNjc4MzRMMC4xMzg2NiAzLjk5MzMzQzAuMDYxNzc5OCAzLjkxNTQ5IDAuMDYxNzEwMiAzLjc5MDMyIDAuMTM4NTA0IDMuNzEyNEwxLjE2MjEzIDIuNjczNzJDMS4yNDAzOCAyLjU5NDMyIDEuMzY4NDMgMi41OTQyMiAxLjQ0NjggMi42NzM0OEwzLjkyMTc0IDUuMTc2NDdMOC41NTMyMyAwLjM5Njk3M1oiCiAgICBmaWxsPSIjOEU4RUE5IgogIC8+Cjwvc3ZnPg==) no-repeat no-repeat center center;
}
.c28:disabled {
background-color: #dcdce4;
border: 1px solid #c0c0cf;
}
.c28:indeterminate {
background-color: #4945ff;
border: 1px solid #4945ff;
}
.c28:indeterminate:after {
content: '';
display: block;
position: relative;
color: white;
height: 2px;
width: 10px;
background-color: #ffffff;
left: 50%;
top: 50%;
-webkit-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
.c28:indeterminate:disabled {
background-color: #dcdce4;
border: 1px solid #c0c0cf;
}
.c28:indeterminate:disabled:after {
background-color: #8e8ea9;
}
.c7 {
display: -webkit-box;
display: -webkit-flex;
@ -489,12 +561,12 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
border-bottom: 1px solid #eaeaef;
}
.c49 {
.c52 {
border-radius: 0 0 4px 4px;
border-top: 1px solid #eaeaef;
}
.c50 > * + * {
.c53 > * + * {
margin-left: 8px;
}
@ -514,13 +586,19 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
max-width: 100%;
}
.c28 {
.c27 {
position: absolute;
top: 12px;
left: 12px;
}
.c31 {
position: absolute;
top: 12px;
right: 12px;
}
.c31 {
.c34 {
margin: 0;
padding: 0;
max-height: 100%;
@ -528,7 +606,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
object-fit: contain;
}
.c30 {
.c33 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
@ -544,18 +622,18 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
border-top-right-radius: 4px;
}
.c37 {
.c40 {
margin-left: auto;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
}
.c40 {
.c43 {
margin-left: 4px;
}
.c34 {
.c37 {
word-break: break-all;
}
@ -564,21 +642,21 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
border-bottom: 1px solid #eaeaef;
}
.c47 {
.c50 {
position: absolute;
bottom: 4px;
right: 4px;
}
.c36 {
.c39 {
text-transform: uppercase;
}
.c29 {
.c32 {
opacity: 0;
}
.c29:focus-within {
.c32:focus-within {
opacity: 1;
}
@ -586,22 +664,22 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
cursor: pointer;
}
.c21:hover .c27 {
.c21:hover .c30 {
opacity: 1;
}
.c45 canvas,
.c45 video {
.c48 canvas,
.c48 video {
display: block;
max-width: 100%;
max-height: 5.5rem;
}
.c44 svg {
.c47 svg {
font-size: 3rem;
}
.c43 {
.c46 {
border-radius: 4px 4px 0 0;
background: linear-gradient(180deg,#ffffff 0%,#f6f6f9 121.48%);
}
@ -717,8 +795,24 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
<div
class="c0 c22 c23"
>
<div>
<div
class="c0 c24 c25 c26 c27"
spacing="2"
>
<div
class="c0 "
>
<input
aria-labelledby="card-1-title"
class="c28"
type="checkbox"
/>
</div>
</div>
</div>
<div
class="c0 c24 c25 c26 c27 c28 c29"
class="c0 c29 c25 c26 c30 c31 c32"
spacing="2"
>
<span>
@ -783,27 +877,27 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</span>
</div>
<div
class="c30"
class="c33"
>
<img
alt="something.jpg"
aria-hidden="true"
class="c31"
class="c34"
src="http://localhost:5000/CPAM.jpg"
/>
</div>
</div>
<div
class="c0 c32"
class="c0 c35"
>
<div
class="c0 c33"
class="c0 c36"
>
<div
class="c0 c34"
class="c0 c37"
>
<div
class="c0 c35"
class="c0 c38"
>
<h2
class="c4 c14"
@ -816,7 +910,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
class="c4 c15"
>
<span
class="c36"
class="c39"
>
jpg
</span>
@ -824,13 +918,13 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</div>
</div>
<div
class="c37"
class="c40"
>
<div
class="c0 c38 c39 c40"
class="c0 c41 c42 c43"
>
<span
class="c4 c41"
class="c4 c44"
>
Image
</span>
@ -857,8 +951,24 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
<div
class="c0 c22 c23"
>
<div>
<div
class="c0 c24 c25 c26 c27"
spacing="2"
>
<div
class="c0 "
>
<input
aria-labelledby="card-6-title"
class="c28"
type="checkbox"
/>
</div>
</div>
</div>
<div
class="c0 c24 c25 c26 c27 c28 c29"
class="c0 c29 c25 c26 c30 c31 c32"
spacing="2"
>
<span>
@ -923,12 +1033,12 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</span>
</div>
<div
class="c0 c42 c22 c43"
class="c0 c45 c22 c46"
height="5.5rem"
width="100%"
>
<span
class="c44"
class="c47"
>
<svg
aria-label="something.pdf"
@ -953,16 +1063,16 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</div>
</div>
<div
class="c0 c32"
class="c0 c35"
>
<div
class="c0 c33"
class="c0 c36"
>
<div
class="c0 c34"
class="c0 c37"
>
<div
class="c0 c35"
class="c0 c38"
>
<h2
class="c4 c14"
@ -975,7 +1085,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
class="c4 c15"
>
<span
class="c36"
class="c39"
>
pdf
</span>
@ -983,13 +1093,13 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</div>
</div>
<div
class="c37"
class="c40"
>
<div
class="c0 c38 c39 c40"
class="c0 c41 c42 c43"
>
<span
class="c4 c41"
class="c4 c44"
>
Doc
</span>
@ -1016,8 +1126,24 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
<div
class="c0 c22 c23"
>
<div>
<div
class="c0 c24 c25 c26 c27"
spacing="2"
>
<div
class="c0 "
>
<input
aria-labelledby="card-11-title"
class="c28"
type="checkbox"
/>
</div>
</div>
</div>
<div
class="c0 c24 c25 c26 c27 c28 c29"
class="c0 c29 c25 c26 c30 c31 c32"
spacing="2"
>
<span>
@ -1082,13 +1208,13 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</span>
</div>
<div
class="c30"
class="c33"
>
<div
class="c0 c25"
>
<div
class="c0 c45"
class="c0 c48"
>
<figure
class="c0 "
@ -1111,26 +1237,26 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</div>
</div>
<time
class="c0 c46 c47"
class="c0 c49 c50"
>
<span
class="c4 c48"
class="c4 c51"
>
...
</span>
</time>
</div>
<div
class="c0 c32"
class="c0 c35"
>
<div
class="c0 c33"
class="c0 c36"
>
<div
class="c0 c34"
class="c0 c37"
>
<div
class="c0 c35"
class="c0 c38"
>
<h2
class="c4 c14"
@ -1143,7 +1269,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
class="c4 c15"
>
<span
class="c36"
class="c39"
>
mp4
</span>
@ -1151,13 +1277,13 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</div>
</div>
<div
class="c37"
class="c40"
>
<div
class="c0 c38 c39 c40"
class="c0 c41 c42 c43"
>
<span
class="c4 c41"
class="c4 c44"
>
Video
</span>
@ -1173,17 +1299,17 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</div>
</div>
<div
class="c0 c1 c49"
class="c0 c1 c52"
>
<div
class="c0 c3"
>
<div
class="c0 c25 c50"
class="c0 c25 c53"
>
<button
aria-disabled="false"
class="c6 c51"
class="c6 c54"
type="button"
>
<span
@ -1194,7 +1320,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</button>
</div>
<div
class="c0 c25 c50"
class="c0 c25 c53"
>
<button
aria-disabled="false"
@ -1212,7 +1338,7 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
</div>
</form>
<div
class="c52"
class="c55"
>
<p
aria-live="polite"

View File

@ -124,9 +124,12 @@ export const MediaLibrary = () => {
...folder,
type: 'folder',
folderURL: getFolderURL(pathname, query, folder.id),
isSelectable: canUpdate,
})) ?? [];
const folderCount = folders?.length || 0;
const assets = assetsData?.results?.map((asset) => ({ ...asset, type: 'asset' })) || [];
const assets =
assetsData?.results?.map((asset) => ({ ...asset, type: 'asset', isSelectable: canUpdate })) ||
[];
const assetCount = assets?.length ?? 0;
const isLoading = isCurrentFolderLoading || foldersLoading || permissionsLoading || assetsLoading;
@ -278,9 +281,7 @@ export const MediaLibrary = () => {
{canRead && !isGridView && (assetCount > 0 || folderCount > 0) && (
<TableList
assetCount={assetCount}
canUpdate={canUpdate}
folderCount={folderCount}
// folderURL={getFolderURL(pathname, query, folderID)}
indeterminate={indeterminateBulkSelect}
onChangeSort={handleChangeSort}
onChangeFolder={(folderID) => push(getFolderURL(pathname, query, folderID))}
@ -339,13 +340,13 @@ export const MediaLibrary = () => {
id={`folder-${folder.id}`}
to={url}
startAction={
selectOne && (
selectOne && folder.isSelectable ? (
<FolderCardCheckbox
data-testid={`folder-checkbox-${folder.id}`}
value={isSelected}
onChange={() => selectOne(folder)}
/>
)
) : undefined
}
cardActions={
<IconButton

View File

@ -225,6 +225,11 @@ describe('Media library homepage', () => {
});
it('hides the select all button when the user is not allowed to update', () => {
useMediaLibraryPermissions.mockReturnValueOnce({
canUpdate: true,
canRead: true,
canCreate: true,
});
useMediaLibraryPermissions.mockReturnValue({
isLoading: false,
canRead: true,
@ -260,6 +265,11 @@ describe('Media library homepage', () => {
describe('create folder', () => {
it('shows the create button if the user has create permissions', () => {
useMediaLibraryPermissions.mockReturnValueOnce({
canUpdate: true,
canRead: true,
canCreate: true,
});
renderML();
expect(screen.getByText('Add new folder')).toBeInTheDocument();
});
@ -353,6 +363,11 @@ describe('Media library homepage', () => {
});
it('displays folder with checked checkbox when is selected', () => {
useMediaLibraryPermissions.mockReturnValueOnce({
canUpdate: true,
canRead: true,
canCreate: true,
});
useSelectionState.mockReturnValueOnce([
[
{
@ -374,7 +389,13 @@ describe('Media library homepage', () => {
});
it('doest not displays folder with checked checkbox when is not selected', () => {
useMediaLibraryPermissions.mockReturnValueOnce({
canUpdate: true,
canRead: true,
canCreate: true,
});
renderML();
expect(screen.getByTestId('folder-checkbox-1')).not.toBeChecked();
});