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:
parent
fbbae7a742
commit
abdcfc6242
|
@ -24,6 +24,8 @@ class MediaTrack < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :media_object, touch: true
|
belongs_to :media_object, touch: true
|
||||||
belongs_to :attachment
|
belongs_to :attachment
|
||||||
|
belongs_to :master_content_tags, class_name: "MasterCourses::MasterContentTag", dependent: :destroy
|
||||||
|
|
||||||
before_validation :set_media_and_attachment
|
before_validation :set_media_and_attachment
|
||||||
before_save :convert_srt_to_wvtt
|
before_save :convert_srt_to_wvtt
|
||||||
before_create :mark_downstream_create_destroy
|
before_create :mark_downstream_create_destroy
|
||||||
|
|
|
@ -76,6 +76,7 @@ module Api::V1::MasterCourses
|
||||||
html_url: url,
|
html_url: url,
|
||||||
locked:
|
locked:
|
||||||
}
|
}
|
||||||
|
json[:locale] = asset.locale if asset.class_name == "MediaTrack"
|
||||||
json[:exceptions] = exceptions[migration_id] || [] unless migration_id.nil?
|
json[:exceptions] = exceptions[migration_id] || [] unless migration_id.nil?
|
||||||
json
|
json
|
||||||
end
|
end
|
||||||
|
|
|
@ -414,4 +414,12 @@ function sortedClosedCaptionLanguageList(userLocale) {
|
||||||
return langlist
|
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,
|
||||||
|
}
|
||||||
|
|
|
@ -26,7 +26,10 @@ import saveMediaRecording, {
|
||||||
saveClosedCaptions,
|
saveClosedCaptions,
|
||||||
saveClosedCaptionsForAttachment,
|
saveClosedCaptionsForAttachment,
|
||||||
} from './saveMediaRecording'
|
} from './saveMediaRecording'
|
||||||
import closedCaptionLanguages, {sortedClosedCaptionLanguageList} from './closedCaptionLanguages'
|
import closedCaptionLanguages, {
|
||||||
|
sortedClosedCaptionLanguageList,
|
||||||
|
captionLanguageForLocale,
|
||||||
|
} from './closedCaptionLanguages'
|
||||||
import getTranslations from './getTranslations'
|
import getTranslations from './getTranslations'
|
||||||
import * as CONSTANTS from './shared/constants'
|
import * as CONSTANTS from './shared/constants'
|
||||||
|
|
||||||
|
@ -45,6 +48,7 @@ export {
|
||||||
saveClosedCaptionsForAttachment,
|
saveClosedCaptionsForAttachment,
|
||||||
closedCaptionLanguages,
|
closedCaptionLanguages,
|
||||||
sortedClosedCaptionLanguageList,
|
sortedClosedCaptionLanguageList,
|
||||||
|
captionLanguageForLocale,
|
||||||
getTranslations,
|
getTranslations,
|
||||||
CONSTANTS,
|
CONSTANTS,
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,15 @@ const unsyncedChanges = [
|
||||||
html_url: '/4/pages/page-1',
|
html_url: '/4/pages/page-1',
|
||||||
locked: false,
|
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 = {
|
const defaultProps = {
|
||||||
|
@ -100,9 +109,21 @@ test('renders the migration options component', () => {
|
||||||
test('renders the changes properly', () => {
|
test('renders the changes properly', () => {
|
||||||
const tree = mount(connect())
|
const tree = mount(connect())
|
||||||
const changes = tree.find('tr[data-testid="bcs__unsynced-item"]')
|
const changes = tree.find('tr[data-testid="bcs__unsynced-item"]')
|
||||||
equal(changes.length, 3)
|
equal(changes.length, 4)
|
||||||
const locks = changes.find('IconBlueprintLockSolid')
|
const locks = changes.find('IconBlueprintLockSolid')
|
||||||
equal(locks.length, 1)
|
equal(locks.length, 1)
|
||||||
const unlocks = changes.find('IconBlueprintSolid')
|
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)
|
||||||
})
|
})
|
||||||
|
|
|
@ -25,11 +25,13 @@ import {View} from '@instructure/ui-view'
|
||||||
import {IconLock, IconUnlock} from '@canvas/blueprint-courses/react/components/BlueprintLocks'
|
import {IconLock, IconUnlock} from '@canvas/blueprint-courses/react/components/BlueprintLocks'
|
||||||
import propTypes from '@canvas/blueprint-courses/react/propTypes'
|
import propTypes from '@canvas/blueprint-courses/react/propTypes'
|
||||||
import {itemTypeLabels, changeTypeLabels} from '@canvas/blueprint-courses/react/labels'
|
import {itemTypeLabels, changeTypeLabels} from '@canvas/blueprint-courses/react/labels'
|
||||||
|
import {captionLanguageForLocale} from '@instructure/canvas-media'
|
||||||
|
|
||||||
const UnsyncedChange = props => {
|
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 changeLabel = changeTypeLabels[change_type] || change_type
|
||||||
const typeLabel = itemTypeLabels[asset_type] || asset_type
|
const typeLabel = itemTypeLabels[asset_type] || asset_type
|
||||||
|
const name = locale ? `${asset_name} (${captionLanguageForLocale(locale)})` : asset_name
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table.Row data-testid="bcs__unsynced-item">
|
<Table.Row data-testid="bcs__unsynced-item">
|
||||||
|
@ -40,7 +42,7 @@ const UnsyncedChange = props => {
|
||||||
</Text>
|
</Text>
|
||||||
<View padding="0 0 0 small">
|
<View padding="0 0 0 small">
|
||||||
<Text size="small" weight="bold">
|
<Text size="small" weight="bold">
|
||||||
{asset_name}
|
{name}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,7 +23,7 @@ import ReactDOM from 'react-dom'
|
||||||
import {parse} from 'url'
|
import {parse} from 'url'
|
||||||
import ready from '@instructure/ready'
|
import ready from '@instructure/ready'
|
||||||
import CanvasMediaPlayer from '@canvas/canvas-media-player'
|
import CanvasMediaPlayer from '@canvas/canvas-media-player'
|
||||||
import {closedCaptionLanguages} from '@instructure/canvas-media'
|
import {captionLanguageForLocale} from '@instructure/canvas-media'
|
||||||
|
|
||||||
const isStandalone = () => {
|
const isStandalone = () => {
|
||||||
return !window.frameElement && window.location === window.top.location
|
return !window.frameElement && window.location === window.top.location
|
||||||
|
@ -84,7 +84,7 @@ ready(() => {
|
||||||
return {
|
return {
|
||||||
id: track.id,
|
id: track.id,
|
||||||
src: track.url,
|
src: track.url,
|
||||||
label: closedCaptionLanguages.find(lang => lang.id === track.locale)?.label || track.locale,
|
label: captionLanguageForLocale(track.locale),
|
||||||
type: track.kind,
|
type: track.kind,
|
||||||
language: track.locale,
|
language: track.locale,
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,59 +21,62 @@ import {useScope as useI18nScope} from '@canvas/i18n'
|
||||||
const I18n = useI18nScope('blueprint_settings_labels')
|
const I18n = useI18nScope('blueprint_settings_labels')
|
||||||
|
|
||||||
const itemTypeLabels = {
|
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() {
|
get announcement() {
|
||||||
return I18n.t('Announcement')
|
return I18n.t('Announcement')
|
||||||
},
|
},
|
||||||
get assessment_question_bank() {
|
get assessment_question_bank() {
|
||||||
return I18n.t('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() {
|
get calendar_event() {
|
||||||
return I18n.t('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() {
|
get learning_outcome() {
|
||||||
return I18n.t('Outcome')
|
return I18n.t('Outcome')
|
||||||
},
|
},
|
||||||
get learning_outcome_group() {
|
get learning_outcome_group() {
|
||||||
return I18n.t('Outcome Group')
|
return I18n.t('Outcome Group')
|
||||||
},
|
},
|
||||||
|
get media_track() {
|
||||||
|
return I18n.t('Caption')
|
||||||
|
},
|
||||||
|
get quiz() {
|
||||||
|
return I18n.t('Quiz')
|
||||||
|
},
|
||||||
get rubric() {
|
get rubric() {
|
||||||
return I18n.t('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() {
|
get settings() {
|
||||||
return I18n.t('Settings')
|
return I18n.t('Settings')
|
||||||
},
|
},
|
||||||
get course_pace() {
|
get syllabus() {
|
||||||
return I18n.t('Course Pace')
|
return I18n.t('Syllabus')
|
||||||
|
},
|
||||||
|
get wiki_page() {
|
||||||
|
return I18n.t('Page')
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +84,12 @@ const itemTypeLabelPlurals = {
|
||||||
get assignment() {
|
get assignment() {
|
||||||
return I18n.t('Assignments')
|
return I18n.t('Assignments')
|
||||||
},
|
},
|
||||||
|
get attachment() {
|
||||||
|
return I18n.t('Files')
|
||||||
|
},
|
||||||
|
get course_pace() {
|
||||||
|
return I18n.t('Course Pace')
|
||||||
|
},
|
||||||
get quiz() {
|
get quiz() {
|
||||||
return I18n.t('Quizzes')
|
return I18n.t('Quizzes')
|
||||||
},
|
},
|
||||||
|
@ -90,12 +99,6 @@ const itemTypeLabelPlurals = {
|
||||||
get wiki_page() {
|
get wiki_page() {
|
||||||
return I18n.t('Pages')
|
return I18n.t('Pages')
|
||||||
},
|
},
|
||||||
get attachment() {
|
|
||||||
return I18n.t('Files')
|
|
||||||
},
|
|
||||||
get course_pace() {
|
|
||||||
return I18n.t('Course Pace')
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeTypeLabels = {
|
const changeTypeLabels = {
|
||||||
|
@ -114,24 +117,24 @@ const changeTypeLabels = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const exceptionTypeLabels = {
|
const exceptionTypeLabels = {
|
||||||
get points() {
|
get availability_dates() {
|
||||||
return I18n.t('Points changed exceptions:')
|
return I18n.t('Availability Dates changed exceptions:')
|
||||||
},
|
},
|
||||||
get content() {
|
get content() {
|
||||||
return I18n.t('Content changed exceptions:')
|
return I18n.t('Content changed exceptions:')
|
||||||
},
|
},
|
||||||
|
get deleted() {
|
||||||
|
return I18n.t('Deleted content exceptions:')
|
||||||
|
},
|
||||||
get due_dates() {
|
get due_dates() {
|
||||||
return I18n.t('Due Dates changed exceptions:')
|
return I18n.t('Due Dates changed exceptions:')
|
||||||
},
|
},
|
||||||
get availability_dates() {
|
get points() {
|
||||||
return I18n.t('Availability Dates changed exceptions:')
|
return I18n.t('Points changed exceptions:')
|
||||||
},
|
},
|
||||||
get settings() {
|
get settings() {
|
||||||
return I18n.t('Settings changed exceptions:')
|
return I18n.t('Settings changed exceptions:')
|
||||||
},
|
},
|
||||||
get deleted() {
|
|
||||||
return I18n.t('Deleted content exceptions:')
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const lockTypeLabel = {
|
const lockTypeLabel = {
|
||||||
|
@ -144,21 +147,21 @@ const lockTypeLabel = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const lockLabels = {
|
const lockLabels = {
|
||||||
|
get availability_dates() {
|
||||||
|
return I18n.t('Availability Dates')
|
||||||
|
},
|
||||||
get content() {
|
get content() {
|
||||||
return I18n.t('Content')
|
return I18n.t('Content')
|
||||||
},
|
},
|
||||||
|
get due_dates() {
|
||||||
|
return I18n.t('Due Dates')
|
||||||
|
},
|
||||||
get points() {
|
get points() {
|
||||||
return I18n.t('Points')
|
return I18n.t('Points')
|
||||||
},
|
},
|
||||||
get settings() {
|
get settings() {
|
||||||
return I18n.t('Settings')
|
return I18n.t('Settings')
|
||||||
},
|
},
|
||||||
get due_dates() {
|
|
||||||
return I18n.t('Due Dates')
|
|
||||||
},
|
|
||||||
get availability_dates() {
|
|
||||||
return I18n.t('Availability Dates')
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
Loading…
Reference in New Issue