mirror of
https://github.com/strapi/strapi.git
synced 2025-09-25 16:29:34 +00:00
refactor isSelectable usage + fix grid view selection
This commit is contained in:
parent
36cf9ea857
commit
1824d5f8be
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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}
|
||||
|
@ -0,0 +1,3 @@
|
||||
export const isSelectable = (allowedTypes, fileType) =>
|
||||
allowedTypes.includes(fileType) ||
|
||||
(allowedTypes.includes('file') && !['video', 'image', 'audio'].includes(fileType));
|
@ -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);
|
||||
});
|
||||
});
|
@ -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),
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
};
|
@ -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);
|
||||
});
|
||||
});
|
@ -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 c28 c29"
|
||||
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 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"
|
||||
>
|
||||
<div
|
||||
class="c0 c33"
|
||||
>
|
||||
<div
|
||||
class="c0 c34"
|
||||
>
|
||||
<div
|
||||
class="c0 c35"
|
||||
>
|
||||
<div
|
||||
class="c0 c36"
|
||||
>
|
||||
<div
|
||||
class="c0 c37"
|
||||
>
|
||||
<div
|
||||
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 c28 c29"
|
||||
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 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"
|
||||
@ -952,17 +1062,17 @@ exports[`PendingAssetStep snapshots the component with valid cards 1`] = `
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="c0 c32"
|
||||
>
|
||||
<div
|
||||
class="c0 c33"
|
||||
>
|
||||
<div
|
||||
class="c0 c34"
|
||||
>
|
||||
<div
|
||||
class="c0 c35"
|
||||
>
|
||||
<div
|
||||
class="c0 c36"
|
||||
>
|
||||
<div
|
||||
class="c0 c37"
|
||||
>
|
||||
<div
|
||||
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 c28 c29"
|
||||
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 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"
|
||||
>
|
||||
<div
|
||||
class="c0 c33"
|
||||
>
|
||||
<div
|
||||
class="c0 c34"
|
||||
>
|
||||
<div
|
||||
class="c0 c35"
|
||||
>
|
||||
<div
|
||||
class="c0 c36"
|
||||
>
|
||||
<div
|
||||
class="c0 c37"
|
||||
>
|
||||
<div
|
||||
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"
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user