feat: New request hook to fetch videos
This commit is contained in:
@@ -26,6 +26,7 @@ import { ErrorAlert } from '../../../../../../sharedComponents/ErrorAlerts/Error
|
||||
import { UploadErrorAlert } from '../../../../../../sharedComponents/ErrorAlerts/UploadErrorAlert';
|
||||
import CollapsibleFormWidget from '../CollapsibleFormWidget';
|
||||
import { ErrorContext } from '../../../../hooks';
|
||||
import { RequestKeys } from '../../../../../../data/constants/requests';
|
||||
|
||||
/**
|
||||
* Collapsible Form widget controlling video handouts
|
||||
@@ -38,6 +39,7 @@ export const HandoutWidget = ({
|
||||
handout,
|
||||
getHandoutDownloadUrl,
|
||||
updateField,
|
||||
isUploadError,
|
||||
}) => {
|
||||
const [error] = React.useContext(ErrorContext).handout;
|
||||
const { fileSizeError } = hooks.fileSizeError();
|
||||
@@ -59,7 +61,7 @@ export const HandoutWidget = ({
|
||||
>
|
||||
<FormattedMessage {...messages.fileSizeError} />
|
||||
</ErrorAlert>
|
||||
<UploadErrorAlert message={messages.uploadHandoutError} />
|
||||
<UploadErrorAlert isUploadError={isUploadError} message={messages.uploadHandoutError} />
|
||||
<FileInput fileInput={fileInput} />
|
||||
{handout ? (
|
||||
<Stack gap={3}>
|
||||
@@ -125,6 +127,7 @@ export const mapStateToProps = (state) => ({
|
||||
isLibrary: selectors.app.isLibrary(state),
|
||||
handout: selectors.video.handout(state),
|
||||
getHandoutDownloadUrl: selectors.video.getHandoutDownloadUrl(state),
|
||||
isUploadError: selectors.requests.isFailed(state, { requestKey: RequestKeys.uploadAsset }),
|
||||
});
|
||||
|
||||
export const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
@@ -24,6 +24,9 @@ jest.mock('../../../../../../data/redux', () => ({
|
||||
app: {
|
||||
isLibrary: jest.fn(args => ({ isLibrary: args })),
|
||||
},
|
||||
requests: {
|
||||
isFailed: jest.fn(args => ({ isFailed: args })),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
@@ -45,8 +45,11 @@ exports[`VideoGallery component snapshot 1`] = `
|
||||
"show": "ShoWERror inPUT",
|
||||
}
|
||||
}
|
||||
isFetchError={false}
|
||||
isFullscreenScroll={false}
|
||||
isLoaded={false}
|
||||
isOpen={true}
|
||||
isUploadError={false}
|
||||
modalMessages={
|
||||
Object {
|
||||
"confirmMsg": Object {
|
||||
|
||||
@@ -98,11 +98,20 @@ export const fileInputHooks = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export const filterAssets = ({ assets }) => {
|
||||
export const buildVideos = ({ rawVideos }) => {
|
||||
let videos = [];
|
||||
const assetsList = Object.values(assets);
|
||||
if (assetsList.length > 0) {
|
||||
videos = assetsList.filter(asset => asset?.contentType?.startsWith('video/'));
|
||||
const videoList = Object.values(rawVideos);
|
||||
if (videoList.length > 0) {
|
||||
videos = videoList.map(asset => ({
|
||||
id: asset.edx_video_id,
|
||||
displayName: asset.client_video_id,
|
||||
externalUrl: asset.course_video_image_url,
|
||||
dateAdded: asset.created,
|
||||
locked: false,
|
||||
thumbnail: asset.course_video_image_url,
|
||||
status: asset.status,
|
||||
duration: asset.duration,
|
||||
}));
|
||||
}
|
||||
return videos;
|
||||
};
|
||||
@@ -130,5 +139,5 @@ export const videoHooks = ({ videos }) => {
|
||||
|
||||
export default {
|
||||
videoHooks,
|
||||
filterAssets,
|
||||
buildVideos,
|
||||
};
|
||||
|
||||
@@ -6,12 +6,16 @@ import hooks from './hooks';
|
||||
import SelectionModal from '../../sharedComponents/SelectionModal';
|
||||
import { acceptedImgKeys } from './utils';
|
||||
import messages from './messages';
|
||||
import { RequestKeys } from '../../data/constants/requests';
|
||||
|
||||
export const VideoGallery = ({
|
||||
// redux
|
||||
assets,
|
||||
rawVideos,
|
||||
isLoaded,
|
||||
isFetchError,
|
||||
isUploadError,
|
||||
}) => {
|
||||
const videos = hooks.filterAssets({ assets });
|
||||
const videos = hooks.buildVideos({ rawVideos });
|
||||
const {
|
||||
galleryError,
|
||||
inputError,
|
||||
@@ -45,6 +49,9 @@ export const VideoGallery = ({
|
||||
selectBtnProps,
|
||||
acceptedFiles: acceptedImgKeys,
|
||||
modalMessages,
|
||||
isLoaded,
|
||||
isUploadError,
|
||||
isFetchError,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -52,11 +59,17 @@ export const VideoGallery = ({
|
||||
};
|
||||
|
||||
VideoGallery.propTypes = {
|
||||
assets: PropTypes.shape({}).isRequired,
|
||||
rawVideos: PropTypes.shape({}).isRequired,
|
||||
isLoaded: PropTypes.bool.isRequired,
|
||||
isFetchError: PropTypes.bool.isRequired,
|
||||
isUploadError: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export const mapStateToProps = (state) => ({
|
||||
assets: selectors.app.assets(state),
|
||||
rawVideos: selectors.app.videos(state),
|
||||
isLoaded: selectors.requests.isFinished(state, { requestKey: RequestKeys.fetchVideos }),
|
||||
isFetchError: selectors.requests.isFailed(state, { requestKey: RequestKeys.fetchVideos }),
|
||||
isUploadError: selectors.requests.isFailed(state, { requestKey: RequestKeys.uploadVideo }),
|
||||
});
|
||||
|
||||
export const mapDispatchToProps = {};
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as module from '.';
|
||||
jest.mock('../../sharedComponents/SelectionModal', () => 'SelectionModal');
|
||||
|
||||
jest.mock('./hooks', () => ({
|
||||
filterAssets: jest.fn(() => []),
|
||||
buildVideos: jest.fn(() => []),
|
||||
videoHooks: jest.fn(() => ({
|
||||
galleryError: {
|
||||
show: 'ShoWERror gAlLery',
|
||||
@@ -44,7 +44,9 @@ jest.mock('./hooks', () => ({
|
||||
jest.mock('../../data/redux', () => ({
|
||||
selectors: {
|
||||
requests: {
|
||||
isPending: (state, { requestKey }) => ({ isPending: { state, requestKey } }),
|
||||
isLoaded: (state, { requestKey }) => ({ isLoaded: { state, requestKey } }),
|
||||
isFetchError: (state, { requestKey }) => ({ isFetchError: { state, requestKey } }),
|
||||
isUploadError: (state, { requestKey }) => ({ isUploadError: { state, requestKey } }),
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -52,7 +54,10 @@ jest.mock('../../data/redux', () => ({
|
||||
describe('VideoGallery', () => {
|
||||
describe('component', () => {
|
||||
const props = {
|
||||
assets: { sOmEaSsET: { staTICUrl: '/assets/sOmEaSsET' } },
|
||||
rawVideos: { sOmEaSsET: { staTICUrl: '/video/sOmEaSsET' } },
|
||||
isLoaded: false,
|
||||
isFetchError: false,
|
||||
isUploadError: false,
|
||||
};
|
||||
let el;
|
||||
const videoHooks = hooks.videoHooks();
|
||||
|
||||
@@ -9,12 +9,14 @@ export const RequestStates = StrictDict({
|
||||
|
||||
export const RequestKeys = StrictDict({
|
||||
fetchAssets: 'fetchAssets',
|
||||
fetchVideos: 'fetchVideos',
|
||||
fetchBlock: 'fetchBlock',
|
||||
fetchImages: 'fetchImages',
|
||||
fetchUnit: 'fetchUnit',
|
||||
fetchStudioView: 'fetchStudioView',
|
||||
saveBlock: 'saveBlock',
|
||||
uploadAsset: 'uploadAsset',
|
||||
uploadVideo: 'uploadVideo',
|
||||
allowThumbnailUpload: 'allowThumbnailUpload',
|
||||
uploadThumbnail: 'uploadThumbnail',
|
||||
uploadTranscript: 'uploadTranscript',
|
||||
|
||||
@@ -16,6 +16,7 @@ const initialState = {
|
||||
studioEndpointUrl: null,
|
||||
lmsEndpointUrl: null,
|
||||
assets: {},
|
||||
videos: {},
|
||||
courseDetails: {},
|
||||
};
|
||||
|
||||
@@ -45,6 +46,7 @@ const app = createSlice({
|
||||
setSaveResponse: (state, { payload }) => ({ ...state, saveResponse: payload }),
|
||||
initializeEditor: (state) => ({ ...state, editorInitialized: true }),
|
||||
setAssets: (state, { payload }) => ({ ...state, assets: payload }),
|
||||
setVideos: (state, { payload }) => ({ ...state, videos: payload }),
|
||||
setCourseDetails: (state, { payload }) => ({ ...state, courseDetails: payload }),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -22,6 +22,7 @@ export const simpleSelectors = {
|
||||
unitUrl: mkSimpleSelector(app => app.unitUrl),
|
||||
blockTitle: mkSimpleSelector(app => app.blockTitle),
|
||||
assets: mkSimpleSelector(app => app.assets),
|
||||
videos: mkSimpleSelector(app => app.videos),
|
||||
};
|
||||
|
||||
export const returnUrl = createSelector(
|
||||
|
||||
@@ -16,6 +16,8 @@ const initialState = {
|
||||
[RequestKeys.deleteTranscript]: { status: RequestStates.inactive },
|
||||
[RequestKeys.fetchCourseDetails]: { status: RequestStates.inactive },
|
||||
[RequestKeys.fetchAssets]: { status: RequestStates.inactive },
|
||||
[RequestKeys.fetchVideos]: { status: RequestStates.inactive },
|
||||
[RequestKeys.uploadVideo]: { status: RequestStates.inactive },
|
||||
[RequestKeys.checkTranscriptsForImport]: { status: RequestStates.inactive },
|
||||
[RequestKeys.importTranscript]: { status: RequestStates.inactive },
|
||||
[RequestKeys.fetchVideoFeatures]: { status: RequestStates.inactive },
|
||||
|
||||
@@ -31,6 +31,12 @@ export const fetchAssets = () => (dispatch) => {
|
||||
}));
|
||||
};
|
||||
|
||||
export const fetchVideos = () => (dispatch) => {
|
||||
dispatch(requests.fetchVideos({
|
||||
onSuccess: (response) => dispatch(actions.app.setVideos(response.data.videos)),
|
||||
}));
|
||||
};
|
||||
|
||||
export const fetchCourseDetails = () => (dispatch) => {
|
||||
dispatch(requests.fetchCourseDetails({
|
||||
onSuccess: (response) => dispatch(actions.app.setCourseDetails(response)),
|
||||
@@ -50,6 +56,7 @@ export const initialize = (data) => (dispatch) => {
|
||||
dispatch(module.fetchUnit());
|
||||
dispatch(module.fetchStudioView());
|
||||
dispatch(module.fetchAssets());
|
||||
dispatch(module.fetchVideos());
|
||||
dispatch(module.fetchCourseDetails());
|
||||
};
|
||||
|
||||
@@ -74,11 +81,6 @@ export const uploadImage = ({ file, setSelection }) => (dispatch) => {
|
||||
}));
|
||||
};
|
||||
|
||||
export const fetchVideos = ({ onSuccess }) => (dispatch) => {
|
||||
dispatch(requests.fetchAssets({ onSuccess }));
|
||||
// onSuccess(mockData.mockVideoData);
|
||||
};
|
||||
|
||||
export default StrictDict({
|
||||
fetchBlock,
|
||||
fetchCourseDetails,
|
||||
|
||||
@@ -9,6 +9,7 @@ jest.mock('./requests', () => ({
|
||||
uploadAsset: (args) => ({ uploadAsset: args }),
|
||||
fetchStudioView: (args) => ({ fetchStudioView: args }),
|
||||
fetchAssets: (args) => ({ fetchAssets: args }),
|
||||
fetchVideos: (args) => ({ fetchVideos: args }),
|
||||
fetchCourseDetails: (args) => ({ fetchCourseDetails: args }),
|
||||
}));
|
||||
|
||||
@@ -105,12 +106,14 @@ describe('app thunkActions', () => {
|
||||
fetchUnit,
|
||||
fetchStudioView,
|
||||
fetchAssets,
|
||||
fetchVideos,
|
||||
fetchCourseDetails,
|
||||
} = thunkActions;
|
||||
thunkActions.fetchBlock = () => 'fetchBlock';
|
||||
thunkActions.fetchUnit = () => 'fetchUnit';
|
||||
thunkActions.fetchStudioView = () => 'fetchStudioView';
|
||||
thunkActions.fetchAssets = () => 'fetchAssets';
|
||||
thunkActions.fetchVideos = () => 'fetchVideos';
|
||||
thunkActions.fetchCourseDetails = () => 'fetchCourseDetails';
|
||||
thunkActions.initialize(testValue)(dispatch);
|
||||
expect(dispatch.mock.calls).toEqual([
|
||||
@@ -119,12 +122,14 @@ describe('app thunkActions', () => {
|
||||
[thunkActions.fetchUnit()],
|
||||
[thunkActions.fetchStudioView()],
|
||||
[thunkActions.fetchAssets()],
|
||||
[thunkActions.fetchVideos()],
|
||||
[thunkActions.fetchCourseDetails()],
|
||||
]);
|
||||
thunkActions.fetchBlock = fetchBlock;
|
||||
thunkActions.fetchUnit = fetchUnit;
|
||||
thunkActions.fetchStudioView = fetchStudioView;
|
||||
thunkActions.fetchAssets = fetchAssets;
|
||||
thunkActions.fetchVideos = fetchVideos;
|
||||
thunkActions.fetchCourseDetails = fetchCourseDetails;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -136,6 +136,18 @@ export const fetchAssets = ({ ...rest }) => (dispatch, getState) => {
|
||||
}));
|
||||
};
|
||||
|
||||
export const fetchVideos = ({ ...rest }) => (dispatch, getState) => {
|
||||
dispatch(module.networkRequest({
|
||||
requestKey: RequestKeys.fetchVideos,
|
||||
promise: api
|
||||
.fetchVideos({
|
||||
studioEndpointUrl: selectors.app.studioEndpointUrl(getState()),
|
||||
learningContextId: selectors.app.learningContextId(getState()),
|
||||
}),
|
||||
...rest,
|
||||
}));
|
||||
};
|
||||
|
||||
export const allowThumbnailUpload = ({ ...rest }) => (dispatch, getState) => {
|
||||
dispatch(module.networkRequest({
|
||||
requestKey: RequestKeys.allowThumbnailUpload,
|
||||
@@ -289,6 +301,7 @@ export default StrictDict({
|
||||
fetchUnit,
|
||||
saveBlock,
|
||||
fetchAssets,
|
||||
fetchVideos,
|
||||
uploadAsset,
|
||||
allowThumbnailUpload,
|
||||
uploadThumbnail,
|
||||
|
||||
@@ -18,6 +18,9 @@ export const apiMethods = {
|
||||
fetchAssets: ({ learningContextId, studioEndpointUrl }) => get(
|
||||
urls.courseAssets({ studioEndpointUrl, learningContextId }),
|
||||
),
|
||||
fetchVideos: ({ studioEndpointUrl, learningContextId }) => get(
|
||||
urls.courseVideos({ studioEndpointUrl, learningContextId }),
|
||||
),
|
||||
fetchCourseDetails: ({ studioEndpointUrl, learningContextId }) => get(
|
||||
urls.courseDetailsUrl({ studioEndpointUrl, learningContextId }),
|
||||
),
|
||||
|
||||
@@ -66,3 +66,7 @@ export const courseAdvanceSettings = ({ studioEndpointUrl, learningContextId })
|
||||
export const videoFeatures = ({ studioEndpointUrl, learningContextId }) => (
|
||||
`${studioEndpointUrl}/video_features/${learningContextId}`
|
||||
);
|
||||
|
||||
export const courseVideos = ({ studioEndpointUrl, learningContextId }) => (
|
||||
`${studioEndpointUrl}/videos/${learningContextId}`
|
||||
);
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import ErrorAlert from './ErrorAlert';
|
||||
import { selectors } from '../../data/redux';
|
||||
import { RequestKeys } from '../../data/constants/requests';
|
||||
|
||||
export const FetchErrorAlert = ({
|
||||
message,
|
||||
// redux
|
||||
isFetchError,
|
||||
// inject
|
||||
}) => (
|
||||
<ErrorAlert
|
||||
isError={isFetchError}
|
||||
@@ -28,12 +23,8 @@ FetchErrorAlert.propTypes = {
|
||||
defaultMessage: PropTypes.string,
|
||||
description: PropTypes.string,
|
||||
}).isRequired,
|
||||
// redux
|
||||
isFetchError: PropTypes.bool.isRequired,
|
||||
|
||||
};
|
||||
export const mapStateToProps = (state) => ({
|
||||
isFetchError: selectors.requests.isFailed(state, { requestKey: RequestKeys.fetchAssets }),
|
||||
});
|
||||
export const mapDispatchToProps = {};
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(FetchErrorAlert);
|
||||
|
||||
export default FetchErrorAlert;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { FetchErrorAlert, mapStateToProps } from './FetchErrorAlert';
|
||||
import { selectors } from '../../data/redux';
|
||||
import { RequestKeys } from '../../data/constants/requests';
|
||||
import { FetchErrorAlert } from './FetchErrorAlert';
|
||||
|
||||
jest.mock('../../data/redux', () => ({
|
||||
selectors: {
|
||||
@@ -18,12 +16,4 @@ describe('FetchErrorAlert', () => {
|
||||
expect(shallow(<FetchErrorAlert isFetchError />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('mapStateToProps', () => {
|
||||
const testState = { A: 'pple', B: 'anana', C: 'ucumber' };
|
||||
test('isFetchError from requests.isFinished', () => {
|
||||
expect(
|
||||
mapStateToProps(testState).isFetchError,
|
||||
).toEqual(selectors.requests.isFailed(testState, { requestKey: RequestKeys.fetchAssets }));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import ErrorAlert from './ErrorAlert';
|
||||
import { selectors } from '../../data/redux';
|
||||
import { RequestKeys } from '../../data/constants/requests';
|
||||
|
||||
export const UploadErrorAlert = ({
|
||||
message,
|
||||
// redux
|
||||
isUploadError,
|
||||
// inject
|
||||
}) => (
|
||||
<ErrorAlert
|
||||
isError={isUploadError}
|
||||
@@ -28,11 +23,7 @@ UploadErrorAlert.propTypes = {
|
||||
defaultMessage: PropTypes.string,
|
||||
description: PropTypes.string,
|
||||
}).isRequired,
|
||||
// redux
|
||||
isUploadError: PropTypes.bool.isRequired,
|
||||
};
|
||||
export const mapStateToProps = (state) => ({
|
||||
isUploadError: selectors.requests.isFailed(state, { requestKey: RequestKeys.uploadAsset }),
|
||||
});
|
||||
export const mapDispatchToProps = {};
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(UploadErrorAlert);
|
||||
|
||||
export default UploadErrorAlert;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { UploadErrorAlert, mapStateToProps } from './UploadErrorAlert';
|
||||
import { selectors } from '../../data/redux';
|
||||
import { RequestKeys } from '../../data/constants/requests';
|
||||
import { UploadErrorAlert } from './UploadErrorAlert';
|
||||
|
||||
jest.mock('../../data/redux', () => ({
|
||||
selectors: {
|
||||
@@ -18,12 +16,4 @@ describe('UploadErrorAlert', () => {
|
||||
expect(shallow(<UploadErrorAlert isUploadError />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('mapStateToProps', () => {
|
||||
const testState = { A: 'pple', B: 'anana', C: 'ucumber' };
|
||||
test('isUploadError from requests.isFinished', () => {
|
||||
expect(
|
||||
mapStateToProps(testState).isUploadError,
|
||||
).toEqual(selectors.requests.isFailed(testState, { requestKey: RequestKeys.uploadAsset }));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import hooks from './hooks';
|
||||
import { acceptedImgKeys } from './utils';
|
||||
import SelectionModal from '../../SelectionModal';
|
||||
import messages from './messages';
|
||||
import { RequestKeys } from '../../../data/constants/requests';
|
||||
import { selectors } from '../../../data/redux';
|
||||
|
||||
export const SelectImageModal = ({
|
||||
isOpen,
|
||||
@@ -10,6 +13,10 @@ export const SelectImageModal = ({
|
||||
setSelection,
|
||||
clearSelection,
|
||||
images,
|
||||
// redux
|
||||
isLoaded,
|
||||
isFetchError,
|
||||
isUploadError,
|
||||
}) => {
|
||||
const {
|
||||
galleryError,
|
||||
@@ -41,6 +48,9 @@ export const SelectImageModal = ({
|
||||
selectBtnProps,
|
||||
acceptedFiles: acceptedImgKeys,
|
||||
modalMessages,
|
||||
isLoaded,
|
||||
isFetchError,
|
||||
isUploadError,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -52,6 +62,18 @@ SelectImageModal.propTypes = {
|
||||
setSelection: PropTypes.func.isRequired,
|
||||
clearSelection: PropTypes.func.isRequired,
|
||||
images: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
// redux
|
||||
isLoaded: PropTypes.bool.isRequired,
|
||||
isFetchError: PropTypes.bool.isRequired,
|
||||
isUploadError: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default SelectImageModal;
|
||||
export const mapStateToProps = (state) => ({
|
||||
isLoaded: selectors.requests.isFinished(state, { requestKey: RequestKeys.fetchAssets }),
|
||||
isFetchError: selectors.requests.isFailed(state, { requestKey: RequestKeys.fetchAssets }),
|
||||
isUploadError: selectors.requests.isFailed(state, { requestKey: RequestKeys.uploadAsset }),
|
||||
});
|
||||
|
||||
export const mapDispatchToProps = {};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(SelectImageModal);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
@@ -13,9 +12,6 @@ import {
|
||||
MessageDescriptor,
|
||||
} from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { selectors } from '../../data/redux';
|
||||
import { RequestKeys } from '../../data/constants/requests';
|
||||
|
||||
import messages from './messages';
|
||||
import GalleryCard from './GalleryCard';
|
||||
|
||||
@@ -28,10 +24,9 @@ export const Gallery = ({
|
||||
emptyGalleryLabel,
|
||||
showIdsOnCards,
|
||||
height,
|
||||
isLoaded,
|
||||
// injected
|
||||
intl,
|
||||
// redux
|
||||
isLoaded,
|
||||
}) => {
|
||||
if (!isLoaded) {
|
||||
return (
|
||||
@@ -80,6 +75,7 @@ Gallery.defaultProps = {
|
||||
emptyGalleryLabel: null,
|
||||
};
|
||||
Gallery.propTypes = {
|
||||
isLoaded: PropTypes.bool.isRequired,
|
||||
galleryIsEmpty: PropTypes.bool.isRequired,
|
||||
searchIsEmpty: PropTypes.bool.isRequired,
|
||||
displayList: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
@@ -90,15 +86,6 @@ Gallery.propTypes = {
|
||||
height: PropTypes.string,
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
// redux
|
||||
isLoaded: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const requestKey = RequestKeys.fetchAssets;
|
||||
export const mapStateToProps = (state) => ({
|
||||
isLoaded: selectors.requests.isFinished(state, { requestKey }),
|
||||
});
|
||||
|
||||
export const mapDispatchToProps = {};
|
||||
|
||||
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Gallery));
|
||||
export default injectIntl(Gallery);
|
||||
|
||||
@@ -2,9 +2,7 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { formatMessage } from '../../../testUtils';
|
||||
import { RequestKeys } from '../../data/constants/requests';
|
||||
import { selectors } from '../../data/redux';
|
||||
import { Gallery, mapStateToProps, mapDispatchToProps } from './Gallery';
|
||||
import { Gallery } from './Gallery';
|
||||
|
||||
jest.mock('../../data/redux', () => ({
|
||||
selectors: {
|
||||
@@ -40,17 +38,4 @@ describe('TextEditor Image Gallery component', () => {
|
||||
expect(shallow(<Gallery {...props} />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('mapStateToProps', () => {
|
||||
const testState = { some: 'testState' };
|
||||
test('loads isLoaded from requests.isFinished selector for fetchAssets request', () => {
|
||||
expect(mapStateToProps(testState).isLoaded).toEqual(
|
||||
selectors.requests.isFinished(testState, { requestKey: RequestKeys.fetchAssets }),
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('mapDispatchToProps', () => {
|
||||
test('is empty', () => {
|
||||
expect(mapDispatchToProps).toEqual({});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -60,6 +60,8 @@ GalleryCard.propTypes = {
|
||||
portableUrl: PropTypes.string,
|
||||
thumbnail: PropTypes.string,
|
||||
url: PropTypes.string,
|
||||
duration: PropTypes.number,
|
||||
status: PropTypes.string,
|
||||
}).isRequired,
|
||||
showId: PropTypes.bool,
|
||||
};
|
||||
|
||||
@@ -31,6 +31,9 @@ export const SelectionModal = ({
|
||||
selectBtnProps,
|
||||
acceptedFiles,
|
||||
modalMessages,
|
||||
isLoaded,
|
||||
isFetchError,
|
||||
isUploadError,
|
||||
// injected
|
||||
intl,
|
||||
}) => {
|
||||
@@ -41,6 +44,10 @@ export const SelectionModal = ({
|
||||
fetchError,
|
||||
uploadError,
|
||||
} = modalMessages;
|
||||
const galleryPropsValues = {
|
||||
isLoaded,
|
||||
...galleryProps,
|
||||
};
|
||||
return (
|
||||
<BaseModal
|
||||
close={close}
|
||||
@@ -60,8 +67,8 @@ export const SelectionModal = ({
|
||||
title={intl.formatMessage(titleMsg)}
|
||||
>
|
||||
{/* Error Alerts */}
|
||||
<FetchErrorAlert message={fetchError} />
|
||||
<UploadErrorAlert message={uploadError} />
|
||||
<FetchErrorAlert isFetchError={isFetchError} message={fetchError} />
|
||||
<UploadErrorAlert isUploadError={isUploadError} message={uploadError} />
|
||||
<ErrorAlert
|
||||
dismissError={inputError.dismiss}
|
||||
hideHeading
|
||||
@@ -80,7 +87,7 @@ export const SelectionModal = ({
|
||||
</ErrorAlert>
|
||||
<Stack gap={3}>
|
||||
<SearchSort {...searchSortProps} />
|
||||
<Gallery {...galleryProps} />
|
||||
<Gallery {...galleryPropsValues} />
|
||||
<FileInput fileInput={fileInput} acceptedFiles={Object.values(acceptedFiles).join()} />
|
||||
</Stack>
|
||||
</BaseModal>
|
||||
@@ -124,6 +131,9 @@ SelectionModal.propTypes = {
|
||||
fetchError: MessageDescriptor,
|
||||
uploadError: MessageDescriptor,
|
||||
}).isRequired,
|
||||
isLoaded: PropTypes.bool.isRequired,
|
||||
isFetchError: PropTypes.bool.isRequired,
|
||||
isUploadError: PropTypes.bool.isRequired,
|
||||
// injected
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user