Cleanup BP change page for captions

fixes LF-389
flag=media_links_use_attachment_id
QA-risk: low

Test plan
- Have a BP course set up
- Upload a media file with captions
- Go to the blueprint unsynced changes
  page and make sure media tracks
  give useful information to the user
  about what's being changed

Change-Id: I76462867c533981f176720b7529b544ab4102085
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/320319
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Jacob DeWar <jacob.dewar@instructure.com>
QA-Review: Jacob DeWar <jacob.dewar@instructure.com>
Product-Review: Mysti Lilla <mysti@instructure.com>
This commit is contained in:
Mysti Lilla 2023-06-06 19:07:59 -06:00
parent fbbae7a742
commit abdcfc6242
8 changed files with 100 additions and 59 deletions

View File

@ -24,6 +24,8 @@ class MediaTrack < ActiveRecord::Base
belongs_to :user
belongs_to :media_object, touch: true
belongs_to :attachment
belongs_to :master_content_tags, class_name: "MasterCourses::MasterContentTag", dependent: :destroy
before_validation :set_media_and_attachment
before_save :convert_srt_to_wvtt
before_create :mark_downstream_create_destroy

View File

@ -76,6 +76,7 @@ module Api::V1::MasterCourses
html_url: url,
locked:
}
json[:locale] = asset.locale if asset.class_name == "MediaTrack"
json[:exceptions] = exceptions[migration_id] || [] unless migration_id.nil?
json
end

View File

@ -414,4 +414,12 @@ function sortedClosedCaptionLanguageList(userLocale) {
return langlist
}
export {sortedClosedCaptionLanguageList, closedCaptionLanguages as default}
function captionLanguageForLocale(locale) {
return closedCaptionLanguages.find(lang => lang.id === locale)?.label || locale
}
export {
sortedClosedCaptionLanguageList,
captionLanguageForLocale,
closedCaptionLanguages as default,
}

View File

@ -26,7 +26,10 @@ import saveMediaRecording, {
saveClosedCaptions,
saveClosedCaptionsForAttachment,
} from './saveMediaRecording'
import closedCaptionLanguages, {sortedClosedCaptionLanguageList} from './closedCaptionLanguages'
import closedCaptionLanguages, {
sortedClosedCaptionLanguageList,
captionLanguageForLocale,
} from './closedCaptionLanguages'
import getTranslations from './getTranslations'
import * as CONSTANTS from './shared/constants'
@ -45,6 +48,7 @@ export {
saveClosedCaptionsForAttachment,
closedCaptionLanguages,
sortedClosedCaptionLanguageList,
captionLanguageForLocale,
getTranslations,
CONSTANTS,
}

View File

@ -49,6 +49,15 @@ const unsyncedChanges = [
html_url: '/4/pages/page-1',
locked: false,
},
{
asset_id: '5',
asset_type: 'media_track',
asset_name: 'media.mp4',
change_type: 'created',
html_url: '/media_attachments/96/media_tracks',
locked: false,
locale: 'en',
},
]
const defaultProps = {
@ -100,9 +109,21 @@ test('renders the migration options component', () => {
test('renders the changes properly', () => {
const tree = mount(connect())
const changes = tree.find('tr[data-testid="bcs__unsynced-item"]')
equal(changes.length, 3)
equal(changes.length, 4)
const locks = changes.find('IconBlueprintLockSolid')
equal(locks.length, 1)
const unlocks = changes.find('IconBlueprintSolid')
equal(unlocks.length, 2)
equal(unlocks.length, 3)
})
test('renders the media tracks properly', () => {
const tree = mount(connect())
const changes = tree.find('tr[data-testid="bcs__unsynced-item"]')
equal(changes.length, 4)
const assetName = changes.findWhere(
node => node.name() === 'Text' && node.text() === 'media.mp4 (English)'
)
equal(assetName.length, 1)
const assetType = changes.findWhere(node => node.name() === 'Text' && node.text() === 'Caption')
equal(assetType.length, 1)
})

View File

@ -25,11 +25,13 @@ import {View} from '@instructure/ui-view'
import {IconLock, IconUnlock} from '@canvas/blueprint-courses/react/components/BlueprintLocks'
import propTypes from '@canvas/blueprint-courses/react/propTypes'
import {itemTypeLabels, changeTypeLabels} from '@canvas/blueprint-courses/react/labels'
import {captionLanguageForLocale} from '@instructure/canvas-media'
const UnsyncedChange = props => {
const {asset_type, asset_name, change_type, locked} = props.change
const {asset_type, asset_name, change_type, locked, locale} = props.change
const changeLabel = changeTypeLabels[change_type] || change_type
const typeLabel = itemTypeLabels[asset_type] || asset_type
const name = locale ? `${asset_name} (${captionLanguageForLocale(locale)})` : asset_name
return (
<Table.Row data-testid="bcs__unsynced-item">
@ -40,7 +42,7 @@ const UnsyncedChange = props => {
</Text>
<View padding="0 0 0 small">
<Text size="small" weight="bold">
{asset_name}
{name}
</Text>
</View>
</div>

View File

@ -23,7 +23,7 @@ import ReactDOM from 'react-dom'
import {parse} from 'url'
import ready from '@instructure/ready'
import CanvasMediaPlayer from '@canvas/canvas-media-player'
import {closedCaptionLanguages} from '@instructure/canvas-media'
import {captionLanguageForLocale} from '@instructure/canvas-media'
const isStandalone = () => {
return !window.frameElement && window.location === window.top.location
@ -84,7 +84,7 @@ ready(() => {
return {
id: track.id,
src: track.url,
label: closedCaptionLanguages.find(lang => lang.id === track.locale)?.label || track.locale,
label: captionLanguageForLocale(track.locale),
type: track.kind,
language: track.locale,
}

View File

@ -21,59 +21,62 @@ import {useScope as useI18nScope} from '@canvas/i18n'
const I18n = useI18nScope('blueprint_settings_labels')
const itemTypeLabels = {
get assignment() {
return I18n.t('Assignment')
},
get assignment_group() {
return I18n.t('Assignment Group')
},
get quiz() {
return I18n.t('Quiz')
},
get discussion_topic() {
return I18n.t('Discussion')
},
get wiki_page() {
return I18n.t('Page')
},
get attachment() {
return I18n.t('File')
},
get context_module() {
return I18n.t('Module')
},
get announcement() {
return I18n.t('Announcement')
},
get assessment_question_bank() {
return I18n.t('Question Bank')
},
get assignment() {
return I18n.t('Assignment')
},
get assignment_group() {
return I18n.t('Assignment Group')
},
get attachment() {
return I18n.t('File')
},
get calendar_event() {
return I18n.t('Event')
},
get context_external_tool() {
return I18n.t('External Tool')
},
get context_module() {
return I18n.t('Module')
},
get course_pace() {
return I18n.t('Course Pace')
},
get discussion_topic() {
return I18n.t('Discussion')
},
get folder() {
return I18n.t('Folder')
},
get learning_outcome() {
return I18n.t('Outcome')
},
get learning_outcome_group() {
return I18n.t('Outcome Group')
},
get media_track() {
return I18n.t('Caption')
},
get quiz() {
return I18n.t('Quiz')
},
get rubric() {
return I18n.t('Rubric')
},
get context_external_tool() {
return I18n.t('External Tool')
},
get folder() {
return I18n.t('Folder')
},
get syllabus() {
return I18n.t('Syllabus')
},
get settings() {
return I18n.t('Settings')
},
get course_pace() {
return I18n.t('Course Pace')
get syllabus() {
return I18n.t('Syllabus')
},
get wiki_page() {
return I18n.t('Page')
},
}
@ -81,6 +84,12 @@ const itemTypeLabelPlurals = {
get assignment() {
return I18n.t('Assignments')
},
get attachment() {
return I18n.t('Files')
},
get course_pace() {
return I18n.t('Course Pace')
},
get quiz() {
return I18n.t('Quizzes')
},
@ -90,12 +99,6 @@ const itemTypeLabelPlurals = {
get wiki_page() {
return I18n.t('Pages')
},
get attachment() {
return I18n.t('Files')
},
get course_pace() {
return I18n.t('Course Pace')
},
}
const changeTypeLabels = {
@ -114,24 +117,24 @@ const changeTypeLabels = {
}
const exceptionTypeLabels = {
get points() {
return I18n.t('Points changed exceptions:')
get availability_dates() {
return I18n.t('Availability Dates changed exceptions:')
},
get content() {
return I18n.t('Content changed exceptions:')
},
get deleted() {
return I18n.t('Deleted content exceptions:')
},
get due_dates() {
return I18n.t('Due Dates changed exceptions:')
},
get availability_dates() {
return I18n.t('Availability Dates changed exceptions:')
get points() {
return I18n.t('Points changed exceptions:')
},
get settings() {
return I18n.t('Settings changed exceptions:')
},
get deleted() {
return I18n.t('Deleted content exceptions:')
},
}
const lockTypeLabel = {
@ -144,21 +147,21 @@ const lockTypeLabel = {
}
const lockLabels = {
get availability_dates() {
return I18n.t('Availability Dates')
},
get content() {
return I18n.t('Content')
},
get due_dates() {
return I18n.t('Due Dates')
},
get points() {
return I18n.t('Points')
},
get settings() {
return I18n.t('Settings')
},
get due_dates() {
return I18n.t('Due Dates')
},
get availability_dates() {
return I18n.t('Availability Dates')
},
}
export {