fix: sort of boolean columns (#705)

This commit is contained in:
Kristin Aoki
2023-11-28 13:13:54 -05:00
committed by GitHub
parent 7030d6c1ba
commit 2402769d9d
8 changed files with 48 additions and 342 deletions

View File

@@ -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 = {

View File

@@ -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 }));

View File

@@ -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,
});
});

View File

@@ -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 });

View File

@@ -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'];

View File

@@ -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 = {

View File

@@ -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 }));

View File

@@ -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,
});
});