diff --git a/src/files-and-videos/generic/InfoModal.jsx b/src/files-and-videos/generic/InfoModal.jsx index fd91506c3..8f81149c4 100644 --- a/src/files-and-videos/generic/InfoModal.jsx +++ b/src/files-and-videos/generic/InfoModal.jsx @@ -7,6 +7,7 @@ import { } from '@edx/frontend-platform/i18n'; import { ModalDialog, + Stack, Truncate, } from '@edx/paragon'; @@ -30,6 +31,7 @@ const InfoModal = ({ size="lg" hasCloseButton data-testid="file-info-modal" + style={{ minHeight: '799px' }} > @@ -44,25 +46,29 @@ const InfoModal = ({
- + + +
+
+ +
+ +
+
{sidebar(file)}
-
- -
- ); diff --git a/src/files-and-videos/videos-page/data/utils.js b/src/files-and-videos/videos-page/data/utils.js index f75fc93e0..ab227b1d3 100644 --- a/src/files-and-videos/videos-page/data/utils.js +++ b/src/files-and-videos/videos-page/data/utils.js @@ -72,6 +72,26 @@ export const getLanguages = (availableLanguages) => { return languages; }; +export const getSortedTranscripts = (languages, transcripts) => { + const transcriptDisplayNames = []; + transcripts.forEach(transcript => { + const displayName = languages[transcript]; + transcriptDisplayNames.push(displayName); + }); + + const sortedTranscripts = transcriptDisplayNames.sort(); + const sortedTranscriptCodes = []; + sortedTranscripts.forEach(transcript => { + Object.entries(languages).forEach(([key, value]) => { + if (value === transcript) { + sortedTranscriptCodes.push(key); + } + }); + }); + + return sortedTranscriptCodes; +}; + export const getSupportedFormats = (supportedFileFormats) => { if (isEmpty(supportedFileFormats)) { return null; diff --git a/src/files-and-videos/videos-page/info-sidebar/TranscriptTab.jsx b/src/files-and-videos/videos-page/info-sidebar/TranscriptTab.jsx index c0e947d8a..13131b147 100644 --- a/src/files-and-videos/videos-page/info-sidebar/TranscriptTab.jsx +++ b/src/files-and-videos/videos-page/info-sidebar/TranscriptTab.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; import { isEmpty } from 'lodash'; @@ -6,7 +6,7 @@ import { ErrorAlert } from '@edx/frontend-lib-content-components'; import { Button, Stack } from '@edx/paragon'; import { Add } from '@edx/paragon/icons'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; -import { getLanguages } from '../data/utils'; +import { getLanguages, getSortedTranscripts } from '../data/utils'; import Transcript from './transcript-item'; import { deleteVideoTranscript, @@ -23,6 +23,7 @@ const TranscriptTab = ({ intl, }) => { const dispatch = useDispatch(); + const divRef = useRef(null); const { transcriptStatus, errors } = useSelector(state => state.videos); const { transcriptAvailableLanguages, @@ -35,13 +36,22 @@ const TranscriptTab = ({ } = videoTranscriptSettings; const { transcripts, id, displayName } = video; const languages = getLanguages(transcriptAvailableLanguages); + let sortedTranscripts = getSortedTranscripts(languages, transcripts); + const [previousSelection, setPreviousSelection] = useState(sortedTranscripts); - const [previousSelection, setPreviousSelection] = useState(transcripts); useEffect(() => { dispatch(resetErrors({ errorType: 'transcript' })); - setPreviousSelection(transcripts); + sortedTranscripts = getSortedTranscripts(languages, transcripts); + setPreviousSelection(sortedTranscripts); }, [transcripts]); + const handleAddEmptyTranscript = () => { + setPreviousSelection(['', ...previousSelection]); + if (divRef?.current?.scrollTo) { + divRef.current.scrollTo({ top: 0, behavior: 'smooth' }); + } + }; + const handleTranscript = (data, actionType) => { const { language, @@ -52,7 +62,8 @@ const TranscriptTab = ({ switch (actionType) { case 'delete': if (isEmpty(language)) { - const updatedSelection = previousSelection.filter(selection => selection !== ''); + const updatedSelection = previousSelection; + updatedSelection.shift(); setPreviousSelection(updatedSelection); } else { dispatch(deleteVideoTranscript({ @@ -87,38 +98,42 @@ const TranscriptTab = ({ }; return ( - - -
    - {errors.transcript.map(message => ( -
  • - {intl.formatMessage(messages.errorAlertMessage, { message })} -
  • - ))} -
-
- {previousSelection.map(transcript => ( - - ))} - + +
+ +
    + {errors.transcript.map(message => ( +
  • + {intl.formatMessage(messages.errorAlertMessage, { message })} +
  • + ))} +
+
+ {previousSelection.map(transcript => ( + + ))} +
+
+ +
); }; diff --git a/src/files-and-videos/videos-page/info-sidebar/TranscriptTab.test.jsx b/src/files-and-videos/videos-page/info-sidebar/TranscriptTab.test.jsx index f02d0c710..95dfaee24 100644 --- a/src/files-and-videos/videos-page/info-sidebar/TranscriptTab.test.jsx +++ b/src/files-and-videos/videos-page/info-sidebar/TranscriptTab.test.jsx @@ -281,13 +281,11 @@ describe('TranscriptTab', () => { }); const englishOption = screen.getByText('English'); - const arabicOption = screen.getAllByRole('button', { name: 'Arabic' })[0]; await act(async () => { - expect(arabicOption).toHaveClass('disabled'); fireEvent.click(englishOption); }); - const menuButton = screen.getByTestId('fr-transcript-menu'); + const menuButton = screen.getByTestId('ar-transcript-menu'); await waitFor(() => { fireEvent.click(menuButton); }); @@ -302,8 +300,6 @@ describe('TranscriptTab', () => { await act(async () => { const addFileInput = screen.getAllByLabelText('file-input')[0]; - expect(addFileInput).toBeInTheDocument(); - userEvent.upload(addFileInput, file); }); const addStatus = store.getState().videos.transcriptStatus; @@ -312,7 +308,7 @@ describe('TranscriptTab', () => { const updatedTranscripts = store.getState().models.videos[defaultProps.id].transcripts; - expect(updatedTranscripts).toEqual(['ar', 'en']); + expect(updatedTranscripts).toEqual(['fr', 'en']); }); it('should show error message', async () => { @@ -320,8 +316,6 @@ describe('TranscriptTab', () => { await act(async () => { const addFileInput = screen.getAllByLabelText('file-input')[0]; - expect(addFileInput).toBeInTheDocument(); - userEvent.upload(addFileInput, file); }); @@ -329,7 +323,7 @@ describe('TranscriptTab', () => { expect(addStatus).toEqual(RequestStatus.FAILED); - expect(screen.getAllByText('Failed to replace fr with en.')[0]).toBeVisible(); + expect(screen.getAllByText('Failed to replace ar with en.')[0]).toBeVisible(); }); }); }); diff --git a/src/files-and-videos/videos-page/info-sidebar/transcript-item/LanguageSelect.jsx b/src/files-and-videos/videos-page/info-sidebar/transcript-item/LanguageSelect.jsx index 12ed61c6b..024c14eff 100644 --- a/src/files-and-videos/videos-page/info-sidebar/transcript-item/LanguageSelect.jsx +++ b/src/files-and-videos/videos-page/info-sidebar/transcript-item/LanguageSelect.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Dropdown, Icon } from '@edx/paragon'; -import { Check } from '@edx/paragon/icons'; +import { Check, ExpandMore } from '@edx/paragon/icons'; import { isEmpty } from 'lodash'; const LanguageSelect = ({ @@ -15,7 +15,8 @@ const LanguageSelect = ({ return ( {currentSelection} - - {Object.entries(options).map(([valueKey, text]) => { - if (valueKey === value) { + +
+ {Object.entries(options).map(([valueKey, text]) => { + if (valueKey === value) { + return ( + + {text} + + ); + } + if (!previousSelection.includes(valueKey)) { + return ( + handleSelect(valueKey)} key={`${valueKey}-item`}> + {text} + + ); + } return ( - - {text} - - ); - } - if (!previousSelection.includes(valueKey)) { - return ( - handleSelect(valueKey)} key={`${valueKey}-item`}> + {text} ); - } - return ( - - {text} - - ); - })} + })} +
+
+ +
); diff --git a/src/files-and-videos/videos-page/info-sidebar/transcript-item/Transcript.jsx b/src/files-and-videos/videos-page/info-sidebar/transcript-item/Transcript.jsx index abceab277..eb0fa6703 100644 --- a/src/files-and-videos/videos-page/info-sidebar/transcript-item/Transcript.jsx +++ b/src/files-and-videos/videos-page/info-sidebar/transcript-item/Transcript.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { Card, @@ -27,6 +27,10 @@ const Transcript = ({ const [newLanguage, setNewLanguage] = useState(transcript); const language = transcript; + useEffect(() => { + setNewLanguage(transcript); + }, [transcript]); + const input = useFileInput({ onAddFile: (file) => { handleTranscript({ @@ -49,7 +53,7 @@ const Transcript = ({ return ( <> {isConfirmationOpen ? ( - + )} /> diff --git a/src/index.jsx b/src/index.jsx index 0a8dfae4d..789da867f 100755 --- a/src/index.jsx +++ b/src/index.jsx @@ -89,6 +89,10 @@ initialize({ BBB_LEARN_MORE_URL: process.env.BBB_LEARN_MORE_URL || '', STUDIO_BASE_URL: process.env.STUDIO_BASE_URL || null, STUDIO_SHORT_NAME: process.env.STUDIO_SHORT_NAME || null, + TERMS_OF_SERVICE_URL: process.env.TERMS_OF_SERVICE_URL || null, + PRIVACY_POLICY_URL: process.env.PRIVACY_POLICY_URL || null, + SHOW_ACCESSIBILITY_PAGE: process.env.SHOW_ACCESSIBILITY_PAGE || false, + NOTIFICATION_FEEDBACK_URL: process.env.NOTIFICATION_FEEDBACK_URL || null, }, 'CourseAuthoringConfig'); }, },