Skip to content

Commit 7214c98

Browse files
authored
Merge pull request #1388 from guardian/pf/uploads-page-to-tsx
Convert Uploads page to TypeScript
2 parents 112187b + f1dab90 commit 7214c98

File tree

11 files changed

+218
-209
lines changed

11 files changed

+218
-209
lines changed

public/video-ui/src/components/Header.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default class Header extends React.Component {
2727
};
2828

2929
renderProgress() {
30-
if (this.props.s3Upload.total) {
30+
if (this.props.s3Upload.status === 'uploading') {
3131
// Start prompting the user about reloading the page
3232
window.onbeforeunload = () => {
3333
return false;

public/video-ui/src/components/Pluto/PlutoProjectPicker.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import React, { useEffect } from 'react';
2-
import { ManagedForm, ManagedField } from '../ManagedForm';
3-
import SelectBox from '../FormFields/SelectBox';
4-
import { Video } from '../../services/VideosApi';
1+
import React, { useCallback, useEffect } from 'react';
52
import { useDispatch, useSelector } from 'react-redux';
3+
import { saveVideo } from '../../actions/VideoActions/saveVideo';
4+
import { Video } from '../../services/VideosApi';
65
import {
76
fetchCommissions,
87
fetchProjects,
98
PlutoState
109
} from '../../slices/pluto';
1110
import { AppDispatch, RootState } from '../../util/setupStore';
11+
import SelectBox from '../FormFields/SelectBox';
12+
import { ManagedField, ManagedForm } from '../ManagedForm';
1213

1314
type Props = {
1415
video: Video;
15-
saveVideo: { (video: Video): Promise<void> };
1616
};
1717

1818
const cloneVideoWithoutPlutoProjectId = (video: Video): Video => {
@@ -23,7 +23,7 @@ const cloneVideoWithoutPlutoProjectId = (video: Video): Video => {
2323
return clone;
2424
};
2525

26-
export const PlutoProjectPicker = ({ video, saveVideo }: Props) => {
26+
export const PlutoProjectPicker = ({ video }: Props) => {
2727
const dispatch = useDispatch<AppDispatch>();
2828

2929
const { commissions, projects } = useSelector<RootState, PlutoState>(
@@ -34,15 +34,17 @@ export const PlutoProjectPicker = ({ video, saveVideo }: Props) => {
3434
dispatch(fetchCommissions());
3535
}, []);
3636

37+
const dispatchSaveVideo = (video: Video) => dispatch(saveVideo(video));
38+
3739
useEffect(() => {
3840
const commissionId = video.plutoData?.commissionId;
3941
if (commissionId) {
4042
dispatch(fetchProjects(video.plutoData.commissionId));
4143
}
4244
}, [video.plutoData?.commissionId]);
4345

44-
const onCommissionSelection = () => {
45-
saveVideo(cloneVideoWithoutPlutoProjectId(video)).then(() => {
46+
const onCommissionSelection = useCallback(() => {
47+
dispatchSaveVideo(cloneVideoWithoutPlutoProjectId(video)).then(() => {
4648
// commissionId is expected to be set since this method is a side effect
4749
// of a commissionId being selected, but testing to maintain
4850
// type safety.
@@ -51,12 +53,12 @@ export const PlutoProjectPicker = ({ video, saveVideo }: Props) => {
5153
dispatch(fetchProjects(commissionId));
5254
}
5355
});
54-
};
56+
}, [video]);
5557

5658
return (
5759
<ManagedForm
5860
data={video}
59-
updateData={saveVideo}
61+
updateData={dispatchSaveVideo}
6062
editable={true}
6163
formName="Pluto"
6264
>

public/video-ui/src/components/VideoUpload/AddSelfHostedAsset.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default class AddSelfHostedAsset extends React.Component {
1717
};
1818

1919
render() {
20-
const { video, permissions, uploading, startUpload } = this.props;
20+
const { video, permissions, isUploading, startUpload } = this.props;
2121

2222
if (!permissions || !permissions.addSelfHostedAsset) {
2323
return false;
@@ -34,13 +34,13 @@ export default class AddSelfHostedAsset extends React.Component {
3434
className="form__field__file"
3535
type="file"
3636
onChange={this.setFile}
37-
disabled={uploading}
37+
disabled={isUploading}
3838
accept="video/*,.mxf"
3939
/>
4040
<button
4141
type="button"
4242
className="btn button__secondary__assets"
43-
disabled={!this.state.file || uploading}
43+
disabled={!this.state.file || isUploading}
4444
onClick={() =>
4545
startUpload({
4646
id: video.id,

public/video-ui/src/components/VideoUpload/VideoAsset.test.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ describe('VideoAsset', () => {
166166
expect(deleteButton).toBeDisabled();
167167

168168
// Check that processing status is displayed
169-
expect(screen.getByText('Uploading to YouTube')).toBeInTheDocument();
169+
expect(
170+
screen.getAllByText('Uploading to YouTube').length
171+
).toBeGreaterThan(0);
170172
});
171173

172174
it('does not call selectAsset when disabled activate button is clicked', async () => {

public/video-ui/src/components/VideoUpload/VideoAsset.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,10 @@ export function Asset({
274274
permissions: Record<string, boolean>;
275275
activatingAssetNumber: number;
276276
}) {
277-
const { asset, metadata, processing } = upload;
278277
const dispatch = useDispatch<AppDispatch>();
279278

279+
const { asset, metadata, processing } = upload;
280+
280281
const user = metadata?.user ?? '';
281282
const info = `Asset ${upload.id} - ${metadata?.originalFilename || '(no filename)'}`;
282283
const timestamp = metadata?.startTimestamp || false;
@@ -336,6 +337,7 @@ export function Asset({
336337
<div className="video-trail__item">
337338
<div className="video-trail__upload">
338339
<AssetProgress {...processing} />
340+
<div>{processing.status}</div>
339341
</div>
340342
<div className="video-trail__item__details">
341343
<AssetControls

public/video-ui/src/components/VideoUpload/YoutubeUpload.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default class YoutubeUpload extends React.Component {
3333
className="form__field__file"
3434
type="file"
3535
onChange={this.setFile}
36-
disabled={!canUploadToYouTube || this.props.uploading}
36+
disabled={!canUploadToYouTube || this.props.isUploading}
3737
accept="video/*,.mxf"
3838
/>
3939
{ !canUploadToYouTube ?
@@ -44,7 +44,7 @@ export default class YoutubeUpload extends React.Component {
4444
<button
4545
type="button"
4646
className="btn button__secondary__assets"
47-
disabled={!canUploadToYouTube || this.props.uploading || !this.state.file}
47+
disabled={!canUploadToYouTube || this.props.isUploading || !this.state.file}
4848
onClick={() =>
4949
startUpload({
5050
id: video.id,

public/video-ui/src/pages/Upload/index.jsx

Lines changed: 0 additions & 124 deletions
This file was deleted.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import React, { useEffect } from 'react';
2+
import { useDispatch, useSelector } from 'react-redux';
3+
import { bindActionCreators } from 'redux';
4+
import { createAsset } from '../../actions/VideoActions/createAsset';
5+
import { getVideo } from '../../actions/VideoActions/getVideo';
6+
import { revertAsset } from '../../actions/VideoActions/revertAsset';
7+
import { saveVideo } from '../../actions/VideoActions/saveVideo';
8+
import PlutoProjectLink from '../../components/Pluto/PlutoProjectLink';
9+
import { PlutoProjectPicker } from '../../components/Pluto/PlutoProjectPicker';
10+
import AddAssetFromURL from '../../components/VideoUpload/AddAssetFromURL';
11+
import AddSelfHostedAsset from '../../components/VideoUpload/AddSelfHostedAsset';
12+
import { VideoTrail } from '../../components/VideoUpload/VideoTrail';
13+
import YoutubeUpload from '../../components/VideoUpload/YoutubeUpload';
14+
import { startVideoUpload } from '../../slices/s3Upload';
15+
import { fetchCategories, fetchChannels } from '../../slices/youtube';
16+
import { AppDispatch, RootState } from '../../util/setupStore';
17+
18+
export const VideoUpload = (props: { params: { id: string } }) => {
19+
const dispatch = useDispatch<AppDispatch>();
20+
21+
const store = useSelector(
22+
({
23+
config,
24+
error,
25+
formFieldsWarning,
26+
search,
27+
s3Upload,
28+
usage,
29+
videoEditOpen,
30+
youtube,
31+
video,
32+
uploads
33+
}: RootState) => ({
34+
config,
35+
error,
36+
formFieldsWarning,
37+
search,
38+
s3Upload,
39+
usage,
40+
videoEditOpen,
41+
youtube,
42+
video: video.video,
43+
uploads,
44+
activatingAssetNumber: video.activatingAssetNumber
45+
})
46+
);
47+
48+
useEffect(() => {
49+
dispatch(getVideo(props.params.id));
50+
if (store.youtube.categories.length === 0) {
51+
dispatch(fetchCategories());
52+
}
53+
if (store.youtube.channels.length === 0) {
54+
dispatch(fetchChannels());
55+
}
56+
}, [
57+
dispatch,
58+
props.params.id,
59+
store.youtube.categories,
60+
store.youtube.channels
61+
]);
62+
63+
const isUploading = store.s3Upload.status === 'uploading';
64+
65+
const projectId = store.video.plutoData?.projectId;
66+
67+
return (
68+
<div>
69+
<div className="video__main">
70+
<div className="video__main__header">
71+
<div className="video__detailbox">
72+
<div>
73+
<div className="form__group">
74+
{projectId && <PlutoProjectLink projectId={projectId} />}
75+
<PlutoProjectPicker video={store.video} />
76+
</div>
77+
</div>
78+
<YoutubeUpload
79+
video={store.video}
80+
categories={store.youtube.categories}
81+
channels={store.youtube.channels}
82+
isUploading={isUploading}
83+
saveVideo={bindActionCreators(saveVideo, dispatch)}
84+
startUpload={bindActionCreators(startVideoUpload, dispatch)}
85+
/>
86+
<AddAssetFromURL
87+
video={store.video}
88+
createAsset={bindActionCreators(createAsset, dispatch)}
89+
/>
90+
<AddSelfHostedAsset
91+
video={store.video}
92+
permissions={store.config.permissions}
93+
isUploading={isUploading}
94+
startUpload={bindActionCreators(startVideoUpload, dispatch)}
95+
/>
96+
</div>
97+
<VideoTrail
98+
video={store.video}
99+
uploads={store.uploads}
100+
selectAsset={(version: number) =>
101+
bindActionCreators(revertAsset(store.video.id, version), dispatch)
102+
}
103+
permissions={store.config.permissions}
104+
activatingAssetNumber={store.activatingAssetNumber}
105+
/>
106+
</div>
107+
</div>
108+
</div>
109+
);
110+
};

0 commit comments

Comments
 (0)