fix: sort of boolean columns (#705)
This commit is contained in:
@@ -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 = {
|
||||
|
||||
@@ -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 }));
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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'];
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 }));
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user