@ -1,144 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { css } from '@emotion/core';
|
|
||||||
import styled from '@emotion/styled';
|
|
||||||
import { FileUploadButton } from 'UI';
|
|
||||||
import { buttons, colors, colorsRaw, shadows, zIndex } from 'netlify-cms-ui-default';
|
|
||||||
|
|
||||||
const styles = {
|
|
||||||
button: css`
|
|
||||||
${buttons.button};
|
|
||||||
${buttons.default};
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: 15px;
|
|
||||||
margin-right: 2px;
|
|
||||||
|
|
||||||
&[disabled] {
|
|
||||||
${buttons.disabled};
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
};
|
|
||||||
|
|
||||||
const ActionsContainer = styled.div`
|
|
||||||
text-align: right;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledUploadButton = styled(FileUploadButton)`
|
|
||||||
${styles.button};
|
|
||||||
${buttons.gray};
|
|
||||||
${shadows.dropMain};
|
|
||||||
margin-bottom: 0;
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
height: 0.1px;
|
|
||||||
width: 0.1px;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
opacity: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
position: absolute;
|
|
||||||
z-index: ${zIndex.zIndex0};
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const DeleteButton = styled.button`
|
|
||||||
${styles.button};
|
|
||||||
${buttons.lightRed};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const InsertButton = styled.button`
|
|
||||||
${styles.button};
|
|
||||||
${buttons.green};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const DownloadButton = styled.button`
|
|
||||||
${styles.button};
|
|
||||||
background-color: ${colors.button};
|
|
||||||
color: ${colors.buttonText};
|
|
||||||
|
|
||||||
${props =>
|
|
||||||
props.focused === true &&
|
|
||||||
css`
|
|
||||||
&:focus,
|
|
||||||
&:hover {
|
|
||||||
color: ${colorsRaw.white};
|
|
||||||
background-color: #555a65;
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const UpperActionsContainer = styled.div``;
|
|
||||||
|
|
||||||
const LowerActionsContainer = styled.div`
|
|
||||||
margin-top: 30px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const MediaLibraryActions = ({
|
|
||||||
uploadButtonLabel,
|
|
||||||
deleteButtonLabel,
|
|
||||||
insertButtonLabel,
|
|
||||||
downloadButtonLabel,
|
|
||||||
uploadEnabled,
|
|
||||||
deleteEnabled,
|
|
||||||
insertEnabled,
|
|
||||||
downloadEnabled,
|
|
||||||
insertVisible,
|
|
||||||
imagesOnly,
|
|
||||||
onPersist,
|
|
||||||
onDelete,
|
|
||||||
onInsert,
|
|
||||||
onDownload,
|
|
||||||
}) => (
|
|
||||||
<ActionsContainer>
|
|
||||||
<UpperActionsContainer>
|
|
||||||
<DownloadButton onClick={onDownload} disabled={!downloadEnabled} focused={downloadEnabled}>
|
|
||||||
{downloadButtonLabel}
|
|
||||||
</DownloadButton>
|
|
||||||
<StyledUploadButton
|
|
||||||
label={uploadButtonLabel}
|
|
||||||
imagesOnly={imagesOnly}
|
|
||||||
onChange={onPersist}
|
|
||||||
disabled={!uploadEnabled}
|
|
||||||
/>
|
|
||||||
</UpperActionsContainer>
|
|
||||||
<LowerActionsContainer>
|
|
||||||
<DeleteButton onClick={onDelete} disabled={!deleteEnabled}>
|
|
||||||
{deleteButtonLabel}
|
|
||||||
</DeleteButton>
|
|
||||||
{!insertVisible ? null : (
|
|
||||||
<InsertButton onClick={onInsert} disabled={!insertEnabled}>
|
|
||||||
{insertButtonLabel}
|
|
||||||
</InsertButton>
|
|
||||||
)}
|
|
||||||
</LowerActionsContainer>
|
|
||||||
</ActionsContainer>
|
|
||||||
);
|
|
||||||
|
|
||||||
MediaLibraryActions.propTypes = {
|
|
||||||
uploadButtonLabel: PropTypes.string.isRequired,
|
|
||||||
deleteButtonLabel: PropTypes.string.isRequired,
|
|
||||||
insertButtonLabel: PropTypes.string.isRequired,
|
|
||||||
downloadButtonLabel: PropTypes.string.isRequired,
|
|
||||||
uploadEnabled: PropTypes.bool,
|
|
||||||
deleteEnabled: PropTypes.bool,
|
|
||||||
insertEnabled: PropTypes.bool,
|
|
||||||
insertVisible: PropTypes.bool,
|
|
||||||
downloadEnabled: PropTypes.bool,
|
|
||||||
imagesOnly: PropTypes.bool,
|
|
||||||
onPersist: PropTypes.func.isRequired,
|
|
||||||
onDelete: PropTypes.func.isRequired,
|
|
||||||
onInsert: PropTypes.func.isRequired,
|
|
||||||
onDownload: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MediaLibraryActions;
|
|
@ -0,0 +1,72 @@
|
|||||||
|
import { css } from '@emotion/core';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { FileUploadButton } from 'UI';
|
||||||
|
import { buttons, colors, colorsRaw, shadows, zIndex } from 'netlify-cms-ui-default';
|
||||||
|
|
||||||
|
const styles = {
|
||||||
|
button: css`
|
||||||
|
${buttons.button};
|
||||||
|
${buttons.default};
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 15px;
|
||||||
|
margin-right: 2px;
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
${buttons.disabled};
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UploadButton = styled(FileUploadButton)`
|
||||||
|
${styles.button};
|
||||||
|
${buttons.gray};
|
||||||
|
${shadows.dropMain};
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
height: 0.1px;
|
||||||
|
width: 0.1px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
z-index: ${zIndex.zIndex0};
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const DeleteButton = styled.button`
|
||||||
|
${styles.button};
|
||||||
|
${buttons.lightRed};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const InsertButton = styled.button`
|
||||||
|
${styles.button};
|
||||||
|
${buttons.green};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const DownloadButton = styled.button`
|
||||||
|
${styles.button};
|
||||||
|
background-color: ${colors.button};
|
||||||
|
color: ${colors.buttonText};
|
||||||
|
|
||||||
|
${props =>
|
||||||
|
props.focused === true &&
|
||||||
|
css`
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
color: ${colorsRaw.white};
|
||||||
|
background-color: #555a65;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
`;
|
@ -5,9 +5,7 @@ import { Map } from 'immutable';
|
|||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import { translate } from 'react-polyglot';
|
import { translate } from 'react-polyglot';
|
||||||
import { Modal } from 'UI';
|
import { Modal } from 'UI';
|
||||||
import MediaLibrarySearch from './MediaLibrarySearch';
|
import MediaLibraryTop from './MediaLibraryTop';
|
||||||
import MediaLibraryHeader from './MediaLibraryHeader';
|
|
||||||
import MediaLibraryActions from './MediaLibraryActions';
|
|
||||||
import MediaLibraryCardGrid from './MediaLibraryCardGrid';
|
import MediaLibraryCardGrid from './MediaLibraryCardGrid';
|
||||||
import EmptyMessage from './EmptyMessage';
|
import EmptyMessage from './EmptyMessage';
|
||||||
import { colors } from 'netlify-cms-ui-default';
|
import { colors } from 'netlify-cms-ui-default';
|
||||||
@ -26,12 +24,6 @@ const cardMargin = `10px`;
|
|||||||
*/
|
*/
|
||||||
const cardOutsideWidth = `300px`;
|
const cardOutsideWidth = `300px`;
|
||||||
|
|
||||||
const LibraryTop = styled.div`
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledModal = styled(Modal)`
|
const StyledModal = styled(Modal)`
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 120px auto;
|
grid-template-rows: 120px auto;
|
||||||
@ -114,55 +106,29 @@ const MediaLibraryModal = ({
|
|||||||
(!hasFiles && t('mediaLibrary.mediaLibraryModal.noAssetsFound')) ||
|
(!hasFiles && t('mediaLibrary.mediaLibraryModal.noAssetsFound')) ||
|
||||||
(!hasFilteredFiles && t('mediaLibrary.mediaLibraryModal.noImagesFound')) ||
|
(!hasFilteredFiles && t('mediaLibrary.mediaLibraryModal.noImagesFound')) ||
|
||||||
(!hasSearchResults && t('mediaLibrary.mediaLibraryModal.noResults'));
|
(!hasSearchResults && t('mediaLibrary.mediaLibraryModal.noResults'));
|
||||||
|
|
||||||
const hasSelection = hasMedia && !isEmpty(selectedFile);
|
const hasSelection = hasMedia && !isEmpty(selectedFile);
|
||||||
const shouldShowButtonLoader = isPersisting || isDeleting;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledModal isOpen={isVisible} onClose={handleClose} isPrivate={privateUpload}>
|
<StyledModal isOpen={isVisible} onClose={handleClose} isPrivate={privateUpload}>
|
||||||
<LibraryTop>
|
<MediaLibraryTop
|
||||||
<div>
|
t={t}
|
||||||
<MediaLibraryHeader
|
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
title={`${privateUpload ? t('mediaLibrary.mediaLibraryModal.private') : ''}${
|
privateUpload={privateUpload}
|
||||||
forImage
|
forImage={forImage}
|
||||||
? t('mediaLibrary.mediaLibraryModal.images')
|
|
||||||
: t('mediaLibrary.mediaLibraryModal.mediaAssets')
|
|
||||||
}`}
|
|
||||||
isPrivate={privateUpload}
|
|
||||||
/>
|
|
||||||
<MediaLibrarySearch
|
|
||||||
value={query}
|
|
||||||
onChange={handleSearchChange}
|
|
||||||
onKeyDown={handleSearchKeyDown}
|
|
||||||
placeholder={t('mediaLibrary.mediaLibraryModal.search')}
|
|
||||||
disabled={!dynamicSearchActive && !hasFilteredFiles}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<MediaLibraryActions
|
|
||||||
uploadButtonLabel={
|
|
||||||
isPersisting
|
|
||||||
? t('mediaLibrary.mediaLibraryModal.uploading')
|
|
||||||
: t('mediaLibrary.mediaLibraryModal.upload')
|
|
||||||
}
|
|
||||||
deleteButtonLabel={
|
|
||||||
isDeleting
|
|
||||||
? t('mediaLibrary.mediaLibraryModal.deleting')
|
|
||||||
: t('mediaLibrary.mediaLibraryModal.deleteSelected')
|
|
||||||
}
|
|
||||||
downloadButtonLabel={t('mediaLibrary.mediaLibraryModal.download')}
|
|
||||||
insertButtonLabel={t('mediaLibrary.mediaLibraryModal.chooseSelected')}
|
|
||||||
uploadEnabled={!shouldShowButtonLoader}
|
|
||||||
deleteEnabled={!shouldShowButtonLoader && hasSelection}
|
|
||||||
insertEnabled={hasSelection}
|
|
||||||
downloadEnabled={hasSelection}
|
|
||||||
insertVisible={canInsert}
|
|
||||||
imagesOnly={forImage}
|
|
||||||
onPersist={handlePersist}
|
|
||||||
onDelete={handleDelete}
|
|
||||||
onInsert={handleInsert}
|
|
||||||
onDownload={handleDownload}
|
onDownload={handleDownload}
|
||||||
|
onUpload={handlePersist}
|
||||||
|
query={query}
|
||||||
|
onSearchChange={handleSearchChange}
|
||||||
|
onSearchKeyDown={handleSearchKeyDown}
|
||||||
|
searchDisabled={!dynamicSearchActive && !hasFilteredFiles}
|
||||||
|
onDelete={handleDelete}
|
||||||
|
canInsert={canInsert}
|
||||||
|
onInsert={handleInsert}
|
||||||
|
hasSelection={hasSelection}
|
||||||
|
isPersisting={isPersisting}
|
||||||
|
isDeleting={isDeleting}
|
||||||
/>
|
/>
|
||||||
</LibraryTop>
|
|
||||||
{!shouldShowEmptyMessage ? null : (
|
{!shouldShowEmptyMessage ? null : (
|
||||||
<EmptyMessage content={emptyMessage} isPrivate={privateUpload} />
|
<EmptyMessage content={emptyMessage} isPrivate={privateUpload} />
|
||||||
)}
|
)}
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import MediaLibrarySearch from './MediaLibrarySearch';
|
||||||
|
import MediaLibraryHeader from './MediaLibraryHeader';
|
||||||
|
import { UploadButton, DeleteButton, DownloadButton, InsertButton } from './MediaLibraryButtons';
|
||||||
|
|
||||||
|
const LibraryTop = styled.div`
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const RowContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ButtonsContainer = styled.div`
|
||||||
|
flex-shrink: 0;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MediaLibraryTop = ({
|
||||||
|
t,
|
||||||
|
onClose,
|
||||||
|
privateUpload,
|
||||||
|
forImage,
|
||||||
|
onDownload,
|
||||||
|
onUpload,
|
||||||
|
query,
|
||||||
|
onSearchChange,
|
||||||
|
onSearchKeyDown,
|
||||||
|
searchDisabled,
|
||||||
|
onDelete,
|
||||||
|
canInsert,
|
||||||
|
onInsert,
|
||||||
|
hasSelection,
|
||||||
|
isPersisting,
|
||||||
|
isDeleting,
|
||||||
|
}) => {
|
||||||
|
const shouldShowButtonLoader = isPersisting || isDeleting;
|
||||||
|
const uploadEnabled = !shouldShowButtonLoader;
|
||||||
|
const deleteEnabled = !shouldShowButtonLoader && hasSelection;
|
||||||
|
const downloadEnabled = hasSelection;
|
||||||
|
const insertEnabled = hasSelection;
|
||||||
|
|
||||||
|
const uploadButtonLabel = isPersisting
|
||||||
|
? t('mediaLibrary.mediaLibraryModal.uploading')
|
||||||
|
: t('mediaLibrary.mediaLibraryModal.upload');
|
||||||
|
const deleteButtonLabel = isDeleting
|
||||||
|
? t('mediaLibrary.mediaLibraryModal.deleting')
|
||||||
|
: t('mediaLibrary.mediaLibraryModal.deleteSelected');
|
||||||
|
const downloadButtonLabel = t('mediaLibrary.mediaLibraryModal.download');
|
||||||
|
const insertButtonLabel = t('mediaLibrary.mediaLibraryModal.chooseSelected');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LibraryTop>
|
||||||
|
<RowContainer>
|
||||||
|
<MediaLibraryHeader
|
||||||
|
onClose={onClose}
|
||||||
|
title={`${privateUpload ? t('mediaLibrary.mediaLibraryModal.private') : ''}${
|
||||||
|
forImage
|
||||||
|
? t('mediaLibrary.mediaLibraryModal.images')
|
||||||
|
: t('mediaLibrary.mediaLibraryModal.mediaAssets')
|
||||||
|
}`}
|
||||||
|
isPrivate={privateUpload}
|
||||||
|
/>
|
||||||
|
<ButtonsContainer>
|
||||||
|
<DownloadButton
|
||||||
|
onClick={onDownload}
|
||||||
|
disabled={!downloadEnabled}
|
||||||
|
focused={downloadEnabled}
|
||||||
|
>
|
||||||
|
{downloadButtonLabel}
|
||||||
|
</DownloadButton>
|
||||||
|
<UploadButton
|
||||||
|
label={uploadButtonLabel}
|
||||||
|
imagesOnly={forImage}
|
||||||
|
onChange={onUpload}
|
||||||
|
disabled={!uploadEnabled}
|
||||||
|
/>
|
||||||
|
</ButtonsContainer>
|
||||||
|
</RowContainer>
|
||||||
|
<RowContainer>
|
||||||
|
<MediaLibrarySearch
|
||||||
|
value={query}
|
||||||
|
onChange={onSearchChange}
|
||||||
|
onKeyDown={onSearchKeyDown}
|
||||||
|
placeholder={t('mediaLibrary.mediaLibraryModal.search')}
|
||||||
|
disabled={searchDisabled}
|
||||||
|
/>
|
||||||
|
<ButtonsContainer>
|
||||||
|
<DeleteButton onClick={onDelete} disabled={!deleteEnabled}>
|
||||||
|
{deleteButtonLabel}
|
||||||
|
</DeleteButton>
|
||||||
|
{!canInsert ? null : (
|
||||||
|
<InsertButton onClick={onInsert} disabled={!insertEnabled}>
|
||||||
|
{insertButtonLabel}
|
||||||
|
</InsertButton>
|
||||||
|
)}
|
||||||
|
</ButtonsContainer>
|
||||||
|
</RowContainer>
|
||||||
|
</LibraryTop>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
MediaLibraryTop.propTypes = {
|
||||||
|
t: PropTypes.func.isRequired,
|
||||||
|
onClose: PropTypes.func.isRequired,
|
||||||
|
privateUpload: PropTypes.bool,
|
||||||
|
forImage: PropTypes.bool,
|
||||||
|
onDownload: PropTypes.func.isRequired,
|
||||||
|
onUpload: PropTypes.func.isRequired,
|
||||||
|
query: PropTypes.string,
|
||||||
|
onSearchChange: PropTypes.func.isRequired,
|
||||||
|
onSearchKeyDown: PropTypes.func.isRequired,
|
||||||
|
searchDisabled: PropTypes.bool.isRequired,
|
||||||
|
onDelete: PropTypes.func.isRequired,
|
||||||
|
canInsert: PropTypes.bool,
|
||||||
|
onInsert: PropTypes.func.isRequired,
|
||||||
|
hasSelection: PropTypes.bool.isRequired,
|
||||||
|
isPersisting: PropTypes.bool,
|
||||||
|
isDeleting: PropTypes.bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MediaLibraryTop;
|
Reference in New Issue
Block a user