1- import React , { useEffect } from 'react' ;
1+ import { useIntl } from '@edx/frontend-platform/i18n' ;
2+ import { Container } from '@openedx/paragon' ;
3+ import CourseFilesSlot from 'CourseAuthoring/plugin-slots/CourseFilesSlot' ;
24import PropTypes from 'prop-types' ;
5+ import React , { useEffect } from 'react' ;
36import { useDispatch , useSelector } from 'react-redux' ;
4- import { injectIntl , FormattedMessage , intlShape } from '@edx/frontend-platform/i18n' ;
5- import { CheckboxFilter , Container } from '@openedx/paragon' ;
6- import Placeholder from '../../editors/Placeholder' ;
77
88import { RequestStatus } from '../../data/constants' ;
9- import { useModels , useModel } from '../../generic/model-store' ;
10- import {
11- addAssetFile ,
12- deleteAssetFile ,
13- fetchAssets ,
14- updateAssetLock ,
15- fetchAssetDownload ,
16- getUsagePaths ,
17- resetErrors ,
18- updateAssetOrder ,
19- validateAssetFiles ,
20- } from './data/thunks' ;
21- import messages from './messages' ;
22- import FilesPageProvider from './FilesPageProvider' ;
9+ import Placeholder from '../../editors/Placeholder' ;
10+ import { useModel } from '../../generic/model-store' ;
2311import getPageHeadTitle from '../../generic/utils' ;
24- import {
25- AccessColumn ,
26- ActiveColumn ,
27- EditFileErrors ,
28- FileTable ,
29- ThumbnailColumn ,
30- } from '../generic' ;
31- import { getFileSizeToClosestByte } from '../../utils' ;
32- import FileThumbnail from './FileThumbnail' ;
33- import FileInfoModalSidebar from './FileInfoModalSidebar' ;
34- import FileValidationModal from './FileValidationModal' ;
12+ import { EditFileErrors } from '../generic' ;
13+ import { fetchAssets , resetErrors } from './data/thunks' ;
14+ import FilesPageProvider from './FilesPageProvider' ;
15+ import messages from './messages' ;
3516import './FilesPage.scss' ;
3617
3718const FilesPage = ( {
3819 courseId,
39- // injected
40- intl,
4120} ) => {
4221 const dispatch = useDispatch ( ) ;
22+ const intl = useIntl ( ) ;
4323 const courseDetails = useModel ( 'courseDetails' , courseId ) ;
4424 document . title = getPageHeadTitle ( courseDetails ?. name , intl . formatMessage ( messages . heading ) ) ;
45-
46- useEffect ( ( ) => {
47- dispatch ( fetchAssets ( courseId ) ) ;
48- } , [ courseId ] ) ;
49-
5025 const {
51- assetIds,
5226 loadingStatus,
5327 addingStatus : addAssetStatus ,
5428 deletingStatus : deleteAssetStatus ,
5529 updatingStatus : updateAssetStatus ,
56- usageStatus : usagePathStatus ,
5730 errors : errorMessages ,
5831 } = useSelector ( state => state . assets ) ;
5932
60- const handleErrorReset = ( error ) => dispatch ( resetErrors ( error ) ) ;
61- const handleDeleteFile = ( id ) => dispatch ( deleteAssetFile ( courseId , id ) ) ;
62- const handleDownloadFile = ( selectedRows ) => dispatch ( fetchAssetDownload ( { selectedRows, courseId } ) ) ;
63- const handleAddFile = ( files ) => {
64- handleErrorReset ( { errorType : 'add' } ) ;
65- dispatch ( validateAssetFiles ( courseId , files ) ) ;
66- } ;
67- const handleFileOverwrite = ( close , files ) => {
68- Object . values ( files ) . forEach ( file => dispatch ( addAssetFile ( courseId , file , true ) ) ) ;
69- close ( ) ;
70- } ;
71- const handleLockFile = ( fileId , locked ) => {
72- handleErrorReset ( { errorType : 'lock' } ) ;
73- dispatch ( updateAssetLock ( { courseId, assetId : fileId , locked } ) ) ;
74- } ;
75- const handleUsagePaths = ( asset ) => dispatch ( getUsagePaths ( { asset, courseId } ) ) ;
76- const handleFileOrder = ( { newFileIdOrder, sortType } ) => {
77- dispatch ( updateAssetOrder ( courseId , newFileIdOrder , sortType ) ) ;
78- } ;
79-
80- const thumbnailPreview = ( props ) => FileThumbnail ( props ) ;
81- const infoModalSidebar = ( asset ) => FileInfoModalSidebar ( {
82- asset,
83- handleLockedAsset : handleLockFile ,
84- } ) ;
85-
86- const assets = useModels ( 'assets' , assetIds ) ;
87- const data = {
88- fileIds : assetIds ,
89- loadingStatus,
90- usagePathStatus,
91- usageErrorMessages : errorMessages . usageMetrics ,
92- fileType : 'file' ,
93- } ;
94- const maxFileSize = 20 * 1048576 ;
95-
96- const activeColumn = {
97- id : 'activeStatus' ,
98- Header : intl . formatMessage ( messages . fileActiveColumn ) ,
99- accessor : 'activeStatus' ,
100- Cell : ( { row } ) => ActiveColumn ( { row, pageLoadStatus : loadingStatus } ) ,
101- Filter : CheckboxFilter ,
102- filter : 'exactTextCase' ,
103- filterChoices : [
104- { name : intl . formatMessage ( messages . activeCheckboxLabel ) , value : 'active' } ,
105- { name : intl . formatMessage ( messages . inactiveCheckboxLabel ) , value : 'inactive' } ,
106- ] ,
107- } ;
108- const accessColumn = {
109- id : 'lockStatus' ,
110- Header : intl . formatMessage ( messages . fileAccessColumn ) ,
111- accessor : 'lockStatus' ,
112- Cell : ( { row } ) => AccessColumn ( { row } ) ,
113- Filter : CheckboxFilter ,
114- filterChoices : [
115- { name : intl . formatMessage ( messages . lockedCheckboxLabel ) , value : 'locked' } ,
116- { name : intl . formatMessage ( messages . publicCheckboxLabel ) , value : 'public' } ,
117- ] ,
118- } ;
119- const thumbnailColumn = {
120- id : 'thumbnail' ,
121- Header : '' ,
122- Cell : ( { row } ) => ThumbnailColumn ( { row, thumbnailPreview } ) ,
123- } ;
124- const fileSizeColumn = {
125- id : 'fileSize' ,
126- Header : intl . formatMessage ( messages . fileSizeColumn ) ,
127- accessor : 'fileSize' ,
128- Cell : ( { row } ) => {
129- const { fileSize } = row . original ;
130- return getFileSizeToClosestByte ( fileSize ) ;
131- } ,
132- } ;
33+ useEffect ( ( ) => {
34+ dispatch ( fetchAssets ( courseId ) ) ;
35+ } , [ courseId ] ) ;
13336
134- const tableColumns = [
135- { ...thumbnailColumn } ,
136- {
137- Header : intl . formatMessage ( messages . fileNameColumn ) ,
138- accessor : 'displayName' ,
139- } ,
140- { ...fileSizeColumn } ,
141- {
142- Header : intl . formatMessage ( messages . fileTypeColumn ) ,
143- accessor : 'wrapperType' ,
144- Filter : CheckboxFilter ,
145- filter : 'includesValue' ,
146- filterChoices : [
147- {
148- name : intl . formatMessage ( messages . codeCheckboxLabel ) ,
149- value : 'code' ,
150- } ,
151- {
152- name : intl . formatMessage ( messages . imageCheckboxLabel ) ,
153- value : 'image' ,
154- } ,
155- {
156- name : intl . formatMessage ( messages . documentCheckboxLabel ) ,
157- value : 'document' ,
158- } ,
159- {
160- name : intl . formatMessage ( messages . audioCheckboxLabel ) ,
161- value : 'audio' ,
162- } ,
163- {
164- name : intl . formatMessage ( messages . otherCheckboxLabel ) ,
165- value : 'other' ,
166- } ,
167- ] ,
168- } ,
169- { ...activeColumn } ,
170- { ...accessColumn } ,
171- ] ;
37+ const handleErrorReset = ( error ) => dispatch ( resetErrors ( error ) ) ;
17238
17339 if ( loadingStatus === RequestStatus . DENIED ) {
17440 return (
@@ -190,30 +56,10 @@ const FilesPage = ({
19056 loadingStatus = { loadingStatus }
19157 />
19258 < div className = "h2" >
193- < FormattedMessage { ... messages . heading } />
59+ { intl . formatMessage ( messages . heading ) }
19460 </ div >
19561 { loadingStatus !== RequestStatus . FAILED && (
196- < >
197- < FileTable
198- { ...{
199- courseId,
200- data,
201- handleAddFile,
202- handleDeleteFile,
203- handleDownloadFile,
204- handleLockFile,
205- handleUsagePaths,
206- handleErrorReset,
207- handleFileOrder,
208- tableColumns,
209- maxFileSize,
210- thumbnailPreview,
211- infoModalSidebar,
212- files : assets ,
213- } }
214- />
215- < FileValidationModal { ...{ handleFileOverwrite } } />
216- </ >
62+ < CourseFilesSlot courseId = { courseId } />
21763 ) }
21864 </ Container >
21965 </ FilesPageProvider >
@@ -222,8 +68,6 @@ const FilesPage = ({
22268
22369FilesPage . propTypes = {
22470 courseId : PropTypes . string . isRequired ,
225- // injected
226- intl : intlShape . isRequired ,
22771} ;
22872
229- export default injectIntl ( FilesPage ) ;
73+ export default FilesPage ;
0 commit comments