diff --git a/src/files-and-videos/files-page/FilesPage.jsx b/src/files-and-videos/files-page/FilesPage.jsx index 1111dbc93..8bbf0802f 100644 --- a/src/files-and-videos/files-page/FilesPage.jsx +++ b/src/files-and-videos/files-page/FilesPage.jsx @@ -1,6 +1,5 @@ import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; -import { isEmpty } from 'lodash'; import { useDispatch, useSelector } from 'react-redux'; import { injectIntl, FormattedMessage, intlShape } from '@edx/frontend-platform/i18n'; import { CheckboxFilter, Container } from '@edx/paragon'; @@ -85,25 +84,26 @@ const FilesPage = ({ const maxFileSize = 20 * 1048576; const activeColumn = { - id: 'usageLocations', + id: 'activeStatus', Header: 'Active', - accessor: (({ usageLocations }) => !isEmpty(usageLocations)), + accessor: 'activeStatus', Cell: ({ row }) => ActiveColumn({ row }), Filter: CheckboxFilter, + filter: 'exactTextCase', filterChoices: [ - { name: intl.formatMessage(messages.activeCheckboxLabel), value: true }, - { name: intl.formatMessage(messages.inactiveCheckboxLabel), value: false }, + { name: intl.formatMessage(messages.activeCheckboxLabel), value: 'active' }, + { name: intl.formatMessage(messages.inactiveCheckboxLabel), value: 'inactive' }, ], }; const accessColumn = { - id: 'locked', + id: 'lockStatus', Header: 'Access', - accessor: 'locked', + accessor: 'lockStatus', Cell: ({ row }) => AccessColumn({ row }), Filter: CheckboxFilter, filterChoices: [ - { name: intl.formatMessage(messages.lockedCheckboxLabel), value: true }, - { name: intl.formatMessage(messages.publicCheckboxLabel), value: false }, + { name: intl.formatMessage(messages.lockedCheckboxLabel), value: 'locked' }, + { name: intl.formatMessage(messages.publicCheckboxLabel), value: 'public' }, ], }; const thumbnailColumn = { diff --git a/src/files-and-videos/files-page/data/thunks.js b/src/files-and-videos/files-page/data/thunks.js index 27922f095..5dd502a0d 100644 --- a/src/files-and-videos/files-page/data/thunks.js +++ b/src/files-and-videos/files-page/data/thunks.js @@ -111,6 +111,7 @@ export function updateAssetLock({ assetId, courseId, locked }) { model: { id: assetId, locked, + lockStatus: locked, }, })); dispatch(updateEditStatus({ editType: 'lock', status: RequestStatus.SUCCESSFUL })); @@ -133,11 +134,13 @@ export function getUsagePaths({ asset, courseId }) { try { const { usageLocations } = await getAssetUsagePaths({ assetId: asset.id, courseId }); const assetLocations = usageLocations[asset.id]; + const activeStatus = assetLocations?.length > 0 ? 'active' : 'inactive'; dispatch(updateModel({ modelType: 'assets', model: { id: asset.id, usageLocations: assetLocations, + activeStatus, }, })); dispatch(updateEditStatus({ editType: 'usageMetrics', status: RequestStatus.SUCCESSFUL })); diff --git a/src/files-and-videos/files-page/data/utils.js b/src/files-and-videos/files-page/data/utils.js index 2526b4ad4..676c140ec 100644 --- a/src/files-and-videos/files-page/data/utils.js +++ b/src/files-and-videos/files-page/data/utils.js @@ -24,13 +24,17 @@ export const updateFileValues = (files) => { wrapperType = 'audio'; } - const { dateAdded } = file; + const { dateAdded, locked, usageLocations } = file; const utcDateString = dateAdded.replace(/\bat\b/g, ''); const utcDateTime = new Date(utcDateString).toString(); + const lockStatus = locked ? 'locked' : 'public'; + const activeStatus = usageLocations?.length > 0 ? 'active' : 'inactive'; updatedFiles.push({ ...file, wrapperType, + lockStatus, + activeStatus, dateAdded: utcDateTime, }); }); diff --git a/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.js b/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.js index 149aed54c..7c07deeee 100644 --- a/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.js +++ b/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.js @@ -5,30 +5,8 @@ export const getFilterOptions = (columns) => { const filterableColumns = columns.filter(column => column?.filterChoices); filterableColumns.forEach(column => { - const { id, filterChoices } = column; - let updatedChoices = filterChoices; - - switch (id) { - case 'locked': - updatedChoices = filterChoices.map(choice => ( - { ...choice, value: choice.value ? 'locked' : 'public' } - )); - break; - case 'usageLocations': - updatedChoices = filterChoices.map(choice => ( - { ...choice, value: choice.value ? 'active' : 'inactive' } - )); - break; - case 'transcripts': - updatedChoices = filterChoices.map(choice => ( - { ...choice, value: choice.value ? 'transcribed' : 'notTranscribed' } - )); - break; - default: - break; - } - - allOptions.push(...updatedChoices); + const { filterChoices } = column; + allOptions.push(...filterChoices); }); return allOptions; @@ -39,26 +17,11 @@ export const getCheckedFilters = (state) => { const allFilters = []; filters.forEach(filter => { const { id, value } = filter; - let updatedValues = value; - switch (id) { - case 'locked': - updatedValues = value.map(val => (val ? 'locked' : 'public')); - break; - case 'usageLocations': - updatedValues = value.map(val => (val ? 'active' : 'inactive')); - break; - case 'transcripts': - updatedValues = value.map(val => (val ? 'transcribed' : 'notTranscribed')); - break; - default: - break; - } - - if (isArray(updatedValues)) { - allFilters.push(...updatedValues); + if (isArray(value)) { + allFilters.push(...value); } else { - allFilters.push([id, updatedValues]); + allFilters.push([id, value]); } }); @@ -77,47 +40,7 @@ export const processFilters = (filters, columns, setAllFilters) => { filterableColumns.forEach(({ id, filterChoices }) => { const filterValues = filterChoices.map(choice => choice.value); - let processedFilters = filters; - - switch (id) { - case 'locked': - processedFilters = filters.map(match => { - if (match === 'locked') { - return true; - } - if (match === 'public') { - return false; - } - return match; - }); - break; - case 'usageLocations': - processedFilters = filters.map(match => { - if (match === 'active') { - return true; - } - if (match === 'inactive') { - return false; - } - return match; - }); - break; - case 'transcripts': - processedFilters = filters.map(match => { - if (match === 'transcribed') { - return true; - } - if (match === 'notTranscribed') { - return false; - } - return match; - }); - break; - default: - break; - } - - const matchingFilters = filterValues.filter(value => processedFilters.includes(value)); + const matchingFilters = filterValues.filter(value => filters.includes(value)); if (!isEmpty(matchingFilters)) { allFilters.push({ id, value: matchingFilters }); diff --git a/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.test.js b/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.test.js index 55fdb3a24..824f2b66d 100644 --- a/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.test.js +++ b/src/files-and-videos/generic/table-components/sort-and-filter-modal/utils.test.js @@ -1,84 +1,6 @@ import { getCheckedFilters, getFilterOptions, processFilters } from './utils'; describe('getCheckboxFilters', () => { - describe('switch case locked', () => { - it('should equal array with string locked', () => { - const state = { - filters: [ - { id: 'locked', value: [true] }, - ], - }; - const expected = ['locked']; - const actual = getCheckedFilters(state); - - expect(actual).toEqual(expected); - }); - - it('value attribute should equal public', () => { - const state = { - filters: [ - { id: 'locked', value: [false] }, - ], - }; - const expected = ['public']; - const actual = getCheckedFilters(state); - - expect(actual).toEqual(expected); - }); - }); - - describe('switch case usageLocations', () => { - it('value attribute should equal active', () => { - const state = { - filters: [ - { id: 'usageLocations', value: [true] }, - ], - }; - const expected = ['active']; - const actual = getCheckedFilters(state); - - expect(actual).toEqual(expected); - }); - - it('value attribute should equal inactive', () => { - const state = { - filters: [ - { id: 'usageLocations', value: [false] }, - ], - }; - const expected = ['inactive']; - const actual = getCheckedFilters(state); - - expect(actual).toEqual(expected); - }); - }); - - describe('switch case transcripts', () => { - it('should equal array with string transcribed', () => { - const state = { - filters: [ - { id: 'transcripts', value: [true] }, - ], - }; - const expected = ['transcribed']; - const actual = getCheckedFilters(state); - - expect(actual).toEqual(expected); - }); - - it('should equal array with string notTranscribed', () => { - const state = { - filters: [ - { id: 'transcripts', value: [false] }, - ], - }; - const expected = ['notTranscribed']; - const actual = getCheckedFilters(state); - - expect(actual).toEqual(expected); - }); - }); - describe('switch case default', () => { it('should equal array with string test', () => { const state = { @@ -107,84 +29,6 @@ describe('getCheckboxFilters', () => { }); describe('getFilterOptions', () => { - describe('switch case locked', () => { - it('value attribute should equal locked', () => { - const columns = [ - { id: 'locked', filterChoices: [{ name: 'Locked', value: true }] }, - ]; - const expected = [ - { name: 'Locked', value: 'locked' }, - ]; - const actual = getFilterOptions(columns); - - expect(actual).toEqual(expected); - }); - - it('value attribute should equal public', () => { - const columns = [ - { id: 'locked', filterChoices: [{ name: 'Public', value: false }] }, - ]; - const expected = [ - { name: 'Public', value: 'public' }, - ]; - const actual = getFilterOptions(columns); - - expect(actual).toEqual(expected); - }); - }); - - describe('switch case usageLocation', () => { - it('value attribute should equal active', () => { - const columns = [ - { id: 'usageLocations', filterChoices: [{ name: 'Active', value: true }] }, - ]; - const expected = [ - { name: 'Active', value: 'active' }, - ]; - const actual = getFilterOptions(columns); - - expect(actual).toEqual(expected); - }); - - it('value attribute should equal inactive', () => { - const columns = [ - { id: 'usageLocations', filterChoices: [{ name: 'Inactive', value: false }] }, - ]; - const expected = [ - { name: 'Inactive', value: 'inactive' }, - ]; - const actual = getFilterOptions(columns); - - expect(actual).toEqual(expected); - }); - }); - - describe('switch case transcripts', () => { - it('value attribute should equal transcribed', () => { - const columns = [ - { id: 'transcripts', filterChoices: [{ name: 'Transcribed', value: true }] }, - ]; - const expected = [ - { name: 'Transcribed', value: 'transcribed' }, - ]; - const actual = getFilterOptions(columns); - - expect(actual).toEqual(expected); - }); - - it('value attribute should equal notTranscribed', () => { - const columns = [ - { id: 'transcripts', filterChoices: [{ name: 'Not transcribed', value: false }] }, - ]; - const expected = [ - { name: 'Not transcribed', value: 'notTranscribed' }, - ]; - const actual = getFilterOptions(columns); - - expect(actual).toEqual(expected); - }); - }); - describe('switch case default', () => { it('value attribute should equal test', () => { const columns = [ @@ -217,90 +61,6 @@ describe('processFilters', () => { expect(setAllFilters).toHaveBeenCalledWith(expectedParameter); }); - describe('switch case locked', () => { - it('should call setAllFilters with locked filter', () => { - const filters = ['locked']; - const columns = [ - { id: 'locked', filterChoices: [{ name: 'Locked', value: true }, { name: 'Public', value: false }] }, - ]; - const expectedParameter = [{ id: 'locked', value: [true] }]; - processFilters(filters, columns, setAllFilters); - - expect(setAllFilters).toHaveBeenCalledWith(expectedParameter); - }); - - it('should call setAllFilters with public filter', () => { - const filters = ['public', 'filter']; - const columns = [ - { id: 'locked', filterChoices: [{ name: 'Public', value: false }] }, - { id: 'test', filterChoices: [{ name: 'Filter', value: 'filter' }] }, - ]; - const expectedParameter = [ - { id: 'locked', value: [false] }, - { id: 'test', value: ['filter'] }, - ]; - processFilters(filters, columns, setAllFilters); - - expect(setAllFilters).toHaveBeenCalledWith(expectedParameter); - }); - }); - - describe('switch case usageLocations', () => { - it('should call setAllFilters with active filter', () => { - const filters = ['active']; - const columns = [ - { id: 'usageLocations', filterChoices: [{ name: 'Active', value: true }] }, - ]; - const expectedParameter = [{ id: 'usageLocations', value: [true] }]; - processFilters(filters, columns, setAllFilters); - - expect(setAllFilters).toHaveBeenCalledWith(expectedParameter); - }); - - it('should call setAllFilters with inactive filter', () => { - const filters = ['inactive', 'filter']; - const columns = [ - { id: 'usageLocations', filterChoices: [{ name: 'Inactive', value: false }] }, - { id: 'test', filterChoices: [{ name: 'Filter', value: 'filter' }] }, - ]; - const expectedParameter = [ - { id: 'usageLocations', value: [false] }, - { id: 'test', value: ['filter'] }, - ]; - processFilters(filters, columns, setAllFilters); - - expect(setAllFilters).toHaveBeenCalledWith(expectedParameter); - }); - }); - - describe('switch case transcripts', () => { - it('should call setAllFilters with transcribed filter', () => { - const filters = ['transcribed', 'filter']; - const columns = [ - { id: 'transcripts', filterChoices: [{ name: 'Transcribed', value: true }] }, - { id: 'test', filterChoices: [{ name: 'Filter', value: 'filter' }] }, - ]; - const expectedParameter = [ - { id: 'transcripts', value: [true] }, - { id: 'test', value: ['filter'] }, - ]; - processFilters(filters, columns, setAllFilters); - - expect(setAllFilters).toHaveBeenCalledWith(expectedParameter); - }); - - it('should call setAllFilters with notTranscribed filter', () => { - const filters = ['notTranscribed']; - const columns = [ - { id: 'transcripts', filterChoices: [{ name: 'Not transcribed', value: false }] }, - ]; - const expectedParameter = [{ id: 'transcripts', value: [false] }]; - processFilters(filters, columns, setAllFilters); - - expect(setAllFilters).toHaveBeenCalledWith(expectedParameter); - }); - }); - describe('switch case default', () => { it('should call setAllFilters with test filter', () => { const filters = ['filter']; diff --git a/src/files-and-videos/videos-page/VideosPage.jsx b/src/files-and-videos/videos-page/VideosPage.jsx index 984bf9818..79ebe6ce9 100644 --- a/src/files-and-videos/videos-page/VideosPage.jsx +++ b/src/files-and-videos/videos-page/VideosPage.jsx @@ -1,6 +1,5 @@ import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; -import { isEmpty } from 'lodash'; import { useDispatch, useSelector } from 'react-redux'; import { injectIntl, @@ -111,29 +110,31 @@ const VideosPage = ({ const infoModalSidebar = (video) => VideoInfoModalSidebar({ video }); const maxFileSize = videoUploadMaxFileSize * 1073741824; const transcriptColumn = { - id: 'transcripts', + id: 'transcriptStatus', Header: 'Transcript', - accessor: (({ transcripts }) => !isEmpty(transcripts)), + accessor: 'transcriptStatus', Cell: ({ row }) => { const { transcripts } = row.original; const numOfTranscripts = transcripts?.length; return numOfTranscripts > 0 ? `(${numOfTranscripts}) available` : null; }, Filter: CheckboxFilter, + filter: 'exactTextCase', filterChoices: [ - { name: intl.formatMessage(messages.transcribedCheckboxLabel), value: true }, - { name: intl.formatMessage(messages.notTranscribedCheckboxLabel), value: false }, + { name: intl.formatMessage(messages.transcribedCheckboxLabel), value: 'transcribed' }, + { name: intl.formatMessage(messages.notTranscribedCheckboxLabel), value: 'notTranscribed' }, ], }; const activeColumn = { - id: 'usageLocations', + id: 'activeStatus', Header: 'Active', - accessor: (({ usageLocations }) => !isEmpty(usageLocations)), + accessor: 'activeStatus', Cell: ({ row }) => ActiveColumn({ row }), Filter: CheckboxFilter, + filter: 'exactTextCase', filterChoices: [ - { name: intl.formatMessage(messages.activeCheckboxLabel), value: true }, - { name: intl.formatMessage(messages.inactiveCheckboxLabel), value: false }, + { name: intl.formatMessage(messages.activeCheckboxLabel), value: 'active' }, + { name: intl.formatMessage(messages.inactiveCheckboxLabel), value: 'inactive' }, ], }; const durationColumn = { diff --git a/src/files-and-videos/videos-page/data/thunks.js b/src/files-and-videos/videos-page/data/thunks.js index 42547a471..72719bc1e 100644 --- a/src/files-and-videos/videos-page/data/thunks.js +++ b/src/files-and-videos/videos-page/data/thunks.js @@ -176,11 +176,14 @@ export function deleteVideoTranscript({ apiUrl, }); const updatedTranscripts = transcripts.filter(transcript => transcript !== language); + const transcriptStatus = updatedTranscripts?.length > 0 ? 'transcribed' : 'notTranscribed'; + dispatch(updateModel({ modelType: 'videos', model: { id: videoId, transcripts: updatedTranscripts, + transcriptStatus, }, })); @@ -244,11 +247,14 @@ export function uploadVideoTranscript({ updatedTranscripts = [...transcripts, newLanguage]; } + const transcriptStatus = updatedTranscripts?.length > 0 ? 'transcribed' : 'notTranscribed'; + dispatch(updateModel({ modelType: 'videos', model: { id: videoId, transcripts: updatedTranscripts, + transcriptStatus, }, })); @@ -272,11 +278,14 @@ export function getUsagePaths({ video, courseId }) { try { const { usageLocations } = await getVideoUsagePaths({ videoId: video.id, courseId }); + const activeStatus = usageLocations?.length > 0 ? 'active' : 'inactive'; + dispatch(updateModel({ modelType: 'videos', model: { id: video.id, usageLocations, + activeStatus, }, })); dispatch(updateEditStatus({ editType: 'usageMetrics', status: RequestStatus.SUCCESSFUL })); diff --git a/src/files-and-videos/videos-page/data/utils.js b/src/files-and-videos/videos-page/data/utils.js index a5c4963e4..1843c46e9 100644 --- a/src/files-and-videos/videos-page/data/utils.js +++ b/src/files-and-videos/videos-page/data/utils.js @@ -22,6 +22,8 @@ export const updateFileValues = (files) => { created, courseVideoImageUrl, status, + transcripts, + usageLocations, } = file; const wrapperType = 'video'; @@ -29,6 +31,8 @@ export const updateFileValues = (files) => { if (thumbnail && thumbnail.startsWith('/')) { thumbnail = `${getConfig().STUDIO_BASE_URL}${thumbnail}`; } + const transcriptStatus = transcripts?.length > 0 ? 'transcribed' : 'notTranscribed'; + const activeStatus = usageLocations?.length > 0 ? 'active' : 'inactive'; let uploadStatus = status; if (status === 'Ready' || status === 'Imported') { @@ -45,6 +49,8 @@ export const updateFileValues = (files) => { dateAdded: created.toString(), status: uploadStatus, thumbnail, + transcriptStatus, + activeStatus, }); });