Merge pull request #326 from open-craft/chris/FAL-3383-new-video-editor-flow

[FAL-3383] Implement new video UX flow on new video editor
This commit is contained in:
kenclary
2023-05-18 11:49:10 -04:00
committed by GitHub
49 changed files with 1181 additions and 136 deletions

View File

@@ -13,7 +13,8 @@ exports[`BaseModal ImageUploadModal template component snapshot 1`] = `
<ModalDialog.Header
style={
Object {
"zIndex": 10000,
"boxShadow": "2px 2px 5px rgba(0, 0, 0, 0.3)",
"zIndex": 1,
}
}
>

View File

@@ -30,7 +30,7 @@ export const BaseModal = ({
isFullscreenOnMobile
isFullscreenScroll={isFullscreenScroll}
>
<ModalDialog.Header style={{ zIndex: 10000 }}>
<ModalDialog.Header style={{ zIndex: 1, boxShadow: '2px 2px 5px rgba(0, 0, 0, 0.3)' }}>
<ModalDialog.Title>
{title}
</ModalDialog.Title>

View File

@@ -50,20 +50,20 @@ export const Gallery = ({
}
if (galleryIsEmpty) {
return (
<div className="gallery p-4 bg-gray-100" style={{ height, margin: '0 -1.5rem' }}>
<div className="gallery p-4 bg-light-400" style={{ height, margin: '0 -1.5rem' }}>
<FormattedMessage {...emptyGalleryLabel} />
</div>
);
}
if (searchIsEmpty) {
return (
<div className="gallery p-4 bg-gray-100" style={{ height, margin: '0 -1.5rem' }}>
<div className="gallery p-4 bg-light-400" style={{ height, margin: '0 -1.5rem' }}>
<FormattedMessage {...messages.emptySearchLabel} />
</div>
);
}
return (
<Scrollable className="gallery bg-gray-100" style={{ height, margin: '0 -1.5rem' }}>
<Scrollable className="gallery bg-light-400" style={{ height, margin: '0 -1.5rem' }}>
<div className="p-4">
<SelectableBox.Set
columns={1}

View File

@@ -15,17 +15,27 @@ import LanguageNamesWidget from '../../containers/VideoEditor/components/VideoSe
export const GalleryCard = ({
asset,
}) => (
<SelectableBox className="card bg-white" key={asset.externalUrl} type="radio" value={asset.id} style={{ padding: '10px 20px' }}>
<SelectableBox
className="card bg-white"
key={asset.externalUrl}
type="radio"
value={asset.id}
style={{
padding: '10px 20px',
border: 'none',
boxShadow: 'none',
}}
>
<div className="card-div d-flex flex-row flex-nowrap">
<div style={{
position: 'relative',
width: '200px',
height: '100px',
margin: '16px 0 0 0',
margin: '18px 0 0 0',
}}
>
<Image
style={{ width: '200px', height: '100px' }}
style={{ border: 'none', width: '200px', height: '100px' }}
src={asset.externalUrl}
/>
{ asset.status && asset.statusBadgeVariant && (
@@ -34,13 +44,21 @@ export const GalleryCard = ({
</Badge>
)}
{ asset.duration >= 0 && (
<Badge variant="dark" style={{ position: 'absolute', right: '6px', bottom: '6px' }}>
<Badge
variant="dark"
style={{
position: 'absolute',
right: '6px',
bottom: '6px',
backgroundColor: 'black',
}}
>
{formatDuration(asset.duration)}
</Badge>
)}
</div>
<div className="card-text p-3">
<h3>{asset.displayName}</h3>
<div className="card-text p-3" style={{ marginTop: '10px' }}>
<h3 className="text-primary-500">{asset.displayName}</h3>
{ asset.transcripts && (
<div style={{ margin: '0 0 5px 0' }}>
<LanguageNamesWidget
@@ -48,7 +66,7 @@ export const GalleryCard = ({
/>
</div>
)}
<p style={{ fontSize: '11px' }}>
<p className="text-gray-500" style={{ fontSize: '11px' }}>
<FormattedMessage
{...messages.addedDate}
values={{

View File

@@ -5,19 +5,31 @@ import { Image } from '@edx/paragon';
import { GalleryCard } from './GalleryCard';
describe('GalleryCard component', () => {
const img = {
const asset = {
externalUrl: 'props.img.externalUrl',
displayName: 'props.img.displayName',
dateAdded: 12345,
};
let el;
beforeEach(() => {
el = shallow(<GalleryCard asset={img} />);
el = shallow(<GalleryCard asset={asset} />);
});
test(`snapshot: dateAdded=${img.dateAdded}`, () => {
test(`snapshot: dateAdded=${asset.dateAdded}`, () => {
expect(el).toMatchSnapshot();
});
it('loads Image with src from image external url', () => {
expect(el.find(Image).props().src).toEqual(img.externalUrl);
expect(el.find(Image).props().src).toEqual(asset.externalUrl);
});
it('snapshot with status badge', () => {
el = shallow(<GalleryCard asset={{ ...asset, status: 'failed', statusBadgeVariant: 'danger' }} />);
expect(el).toMatchSnapshot();
});
it('snapshot with duration badge', () => {
el = shallow(<GalleryCard asset={{ ...asset, duration: 60 }} />);
expect(el).toMatchSnapshot();
});
it('snapshot with duration transcripts', () => {
el = shallow(<GalleryCard asset={{ ...asset, transcripts: ['es'] }} />);
expect(el).toMatchSnapshot();
});
});

View File

@@ -57,7 +57,7 @@ export const SearchSort = ({
{ !showSwitch && <ActionRow.Spacer /> }
<Dropdown>
<Dropdown.Toggle id="gallery-sort-button" variant="tertiary">
<Dropdown.Toggle className="text-gray-700" id="gallery-sort-button" variant="tertiary">
<FormattedMessage {...sortMessages[sortBy]} />
</Dropdown.Toggle>
<Dropdown.Menu>
@@ -71,7 +71,7 @@ export const SearchSort = ({
{ filterKeys && filterMessages && (
<Dropdown>
<Dropdown.Toggle id="gallery-filter-button" variant="tertiary">
<Dropdown.Toggle className="text-gray-700" id="gallery-filter-button" variant="tertiary">
<FormattedMessage {...filterMessages[filterBy]} />
</Dropdown.Toggle>
<Dropdown.Menu>
@@ -92,7 +92,7 @@ export const SearchSort = ({
onChange={onSwitchClick}
isInline
>
<Form.Switch value="switch-value" floatLabelLeft>
<Form.Switch className="text-gray-700" value="switch-value" floatLabelLeft>
<FormattedMessage {...switchMessage} />
</Form.Switch>
</Form.SwitchSet>

View File

@@ -2,7 +2,7 @@
exports[`TextEditor Image Gallery component component snapshot: loaded but no images, show empty gallery 1`] = `
<div
className="gallery p-4 bg-gray-100"
className="gallery p-4 bg-light-400"
style={
Object {
"height": "375px",
@@ -16,7 +16,7 @@ exports[`TextEditor Image Gallery component component snapshot: loaded but no im
exports[`TextEditor Image Gallery component component snapshot: loaded but search returns no images, show 0 search result gallery 1`] = `
<div
className="gallery p-4 bg-gray-100"
className="gallery p-4 bg-light-400"
style={
Object {
"height": "375px",
@@ -34,7 +34,7 @@ exports[`TextEditor Image Gallery component component snapshot: loaded but searc
exports[`TextEditor Image Gallery component component snapshot: loaded, show gallery 1`] = `
<Scrollable
className="gallery bg-gray-100"
className="gallery bg-light-400"
style={
Object {
"height": "375px",

View File

@@ -1,11 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`GalleryCard component snapshot: dateAdded=12345 1`] = `
exports[`GalleryCard component snapshot with duration badge 1`] = `
<SelectableBox
className="card bg-white"
key="props.img.externalUrl"
style={
Object {
"border": "none",
"boxShadow": "none",
"padding": "10px 20px",
}
}
@@ -18,7 +20,7 @@ exports[`GalleryCard component snapshot: dateAdded=12345 1`] = `
style={
Object {
"height": "100px",
"margin": "16px 0 0 0",
"margin": "18px 0 0 0",
"position": "relative",
"width": "200px",
}
@@ -28,19 +30,305 @@ exports[`GalleryCard component snapshot: dateAdded=12345 1`] = `
src="props.img.externalUrl"
style={
Object {
"border": "none",
"height": "100px",
"width": "200px",
}
}
/>
<Component
style={
Object {
"backgroundColor": "black",
"bottom": "6px",
"position": "absolute",
"right": "6px",
}
}
variant="dark"
>
01:00
</Component>
</div>
<div
className="card-text p-3"
style={
Object {
"marginTop": "10px",
}
}
>
<h3>
<h3
className="text-primary-500"
>
props.img.displayName
</h3>
<p
className="text-gray-500"
style={
Object {
"fontSize": "11px",
}
}
>
<FormattedMessage
defaultMessage="Added {date} at {time}"
description="File date-added string"
id="authoring.selectionmodal.addedDate.label"
values={
Object {
"date": <FormattedDate
value={12345}
/>,
"time": <FormattedTime
value={12345}
/>,
}
}
/>
</p>
</div>
</div>
</SelectableBox>
`;
exports[`GalleryCard component snapshot with duration transcripts 1`] = `
<SelectableBox
className="card bg-white"
key="props.img.externalUrl"
style={
Object {
"border": "none",
"boxShadow": "none",
"padding": "10px 20px",
}
}
type="radio"
>
<div
className="card-div d-flex flex-row flex-nowrap"
>
<div
style={
Object {
"height": "100px",
"margin": "18px 0 0 0",
"position": "relative",
"width": "200px",
}
}
>
<Image
src="props.img.externalUrl"
style={
Object {
"border": "none",
"height": "100px",
"width": "200px",
}
}
/>
</div>
<div
className="card-text p-3"
style={
Object {
"marginTop": "10px",
}
}
>
<h3
className="text-primary-500"
>
props.img.displayName
</h3>
<div
style={
Object {
"margin": "0 0 5px 0",
}
}
>
<injectIntl(ShimmedIntlComponent)
transcripts={
Array [
"es",
]
}
/>
</div>
<p
className="text-gray-500"
style={
Object {
"fontSize": "11px",
}
}
>
<FormattedMessage
defaultMessage="Added {date} at {time}"
description="File date-added string"
id="authoring.selectionmodal.addedDate.label"
values={
Object {
"date": <FormattedDate
value={12345}
/>,
"time": <FormattedTime
value={12345}
/>,
}
}
/>
</p>
</div>
</div>
</SelectableBox>
`;
exports[`GalleryCard component snapshot with status badge 1`] = `
<SelectableBox
className="card bg-white"
key="props.img.externalUrl"
style={
Object {
"border": "none",
"boxShadow": "none",
"padding": "10px 20px",
}
}
type="radio"
>
<div
className="card-div d-flex flex-row flex-nowrap"
>
<div
style={
Object {
"height": "100px",
"margin": "18px 0 0 0",
"position": "relative",
"width": "200px",
}
}
>
<Image
src="props.img.externalUrl"
style={
Object {
"border": "none",
"height": "100px",
"width": "200px",
}
}
/>
<Component
style={
Object {
"left": "6px",
"position": "absolute",
"top": "6px",
}
}
variant="danger"
>
failed
</Component>
</div>
<div
className="card-text p-3"
style={
Object {
"marginTop": "10px",
}
}
>
<h3
className="text-primary-500"
>
props.img.displayName
</h3>
<p
className="text-gray-500"
style={
Object {
"fontSize": "11px",
}
}
>
<FormattedMessage
defaultMessage="Added {date} at {time}"
description="File date-added string"
id="authoring.selectionmodal.addedDate.label"
values={
Object {
"date": <FormattedDate
value={12345}
/>,
"time": <FormattedTime
value={12345}
/>,
}
}
/>
</p>
</div>
</div>
</SelectableBox>
`;
exports[`GalleryCard component snapshot: dateAdded=12345 1`] = `
<SelectableBox
className="card bg-white"
key="props.img.externalUrl"
style={
Object {
"border": "none",
"boxShadow": "none",
"padding": "10px 20px",
}
}
type="radio"
>
<div
className="card-div d-flex flex-row flex-nowrap"
>
<div
style={
Object {
"height": "100px",
"margin": "18px 0 0 0",
"position": "relative",
"width": "200px",
}
}
>
<Image
src="props.img.externalUrl"
style={
Object {
"border": "none",
"height": "100px",
"width": "200px",
}
}
/>
</div>
<div
className="card-text p-3"
style={
Object {
"marginTop": "10px",
}
}
>
<h3
className="text-primary-500"
>
props.img.displayName
</h3>
<p
className="text-gray-500"
style={
Object {
"fontSize": "11px",

View File

@@ -28,6 +28,7 @@ exports[`SearchSort component snapshots with filterKeys with search string (clos
</Form.Group>
<Dropdown>
<Dropdown.Toggle
className="text-gray-700"
id="gallery-sort-button"
variant="tertiary"
>
@@ -78,6 +79,7 @@ exports[`SearchSort component snapshots with filterKeys with search string (clos
</Dropdown>
<Dropdown>
<Dropdown.Toggle
className="text-gray-700"
id="gallery-filter-button"
variant="tertiary"
>
@@ -138,6 +140,7 @@ exports[`SearchSort component snapshots with filterKeys with search string (clos
onChange={null}
>
<Component
className="text-gray-700"
floatLabelLeft={true}
value="switch-value"
>
@@ -166,6 +169,7 @@ exports[`SearchSort component snapshots with filterKeys without search string (s
</Form.Group>
<Dropdown>
<Dropdown.Toggle
className="text-gray-700"
id="gallery-sort-button"
variant="tertiary"
>
@@ -216,6 +220,7 @@ exports[`SearchSort component snapshots with filterKeys without search string (s
</Dropdown>
<Dropdown>
<Dropdown.Toggle
className="text-gray-700"
id="gallery-filter-button"
variant="tertiary"
>
@@ -276,6 +281,7 @@ exports[`SearchSort component snapshots with filterKeys without search string (s
onChange={null}
>
<Component
className="text-gray-700"
floatLabelLeft={true}
value="switch-value"
>
@@ -314,6 +320,7 @@ exports[`SearchSort component snapshots without filterKeys with search string (c
<ActionRow.Spacer />
<Dropdown>
<Dropdown.Toggle
className="text-gray-700"
id="gallery-sort-button"
variant="tertiary"
>
@@ -385,6 +392,7 @@ exports[`SearchSort component snapshots without filterKeys without search string
<ActionRow.Spacer />
<Dropdown>
<Dropdown.Toggle
className="text-gray-700"
id="gallery-sort-button"
variant="tertiary"
>

View File

@@ -47,7 +47,7 @@ export const SelectionModal = ({
let background = '#FFFFFF';
let showGallery = true;
if (isLoaded && !isFetchError && !isUploadError && !inputError.show) {
background = '#EBEBEB';
background = '#E9E6E4';
} else if (isLoaded) {
showGallery = false;
}
@@ -69,14 +69,22 @@ export const SelectionModal = ({
size={size}
isFullscreenScroll={isFullscreenScroll}
footerAction={(
<Button iconBefore={Add} onClick={fileInput.click} variant="link">
<Button
className="text-primary-500"
iconBefore={Add}
onClick={fileInput.click}
variant="link"
style={{
textDecoration: 'none',
}}
>
<FormattedMessage {...uploadButtonMsg} />
</Button>
)}
title={intl.formatMessage(titleMsg)}
bodyStyle={{ background, padding: '9px 24px' }}
bodyStyle={{ background, padding: '3px 24px' }}
headerComponent={(
<div style={{ zIndex: 10000, margin: '18px 0' }}>
<div style={{ margin: '18px 0' }}>
<SearchSort {...searchSortProps} />
</div>
)}
@@ -132,7 +140,6 @@ SelectionModal.propTypes = {
}).isRequired,
fileInput: PropTypes.shape({
click: PropTypes.func.isRequired,
addFile: PropTypes.func.isRequired,
}).isRequired,
galleryProps: PropTypes.shape({}).isRequired,
searchSortProps: PropTypes.shape({}).isRequired,