refactor: course outline badge status logic
This commit is contained in:
committed by
Kristin Aoki
parent
b417cd64a0
commit
eb0c61ce6d
@@ -211,6 +211,7 @@ const CourseOutline = ({ courseId }) => {
|
||||
background: 'white',
|
||||
padding: '1.75rem',
|
||||
marginBottom: '1.5rem',
|
||||
borderRadius: '0.35rem',
|
||||
boxShadow: '0 0 .125rem rgba(0, 0, 0, .15), 0 0 .25rem rgba(0, 0, 0, .15)',
|
||||
}}
|
||||
>
|
||||
@@ -244,6 +245,7 @@ const CourseOutline = ({ courseId }) => {
|
||||
background: '#f8f7f6',
|
||||
padding: '1rem 1.5rem',
|
||||
marginBottom: '1.5rem',
|
||||
borderRadius: '0.35rem',
|
||||
boxShadow: '0 0 .125rem rgba(0, 0, 0, .15), 0 0 .25rem rgba(0, 0, 0, .15)',
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -21,6 +21,10 @@ const messages = defineMessages({
|
||||
id: 'course-authoring.course-outline.card.status-badge.draft',
|
||||
defaultMessage: 'Draft',
|
||||
},
|
||||
statusBadgeUnpublishedChanges: {
|
||||
id: 'course-authoring.course-outline.card.status-badge.draft-unpublished-changes',
|
||||
defaultMessage: 'Draft (Unpublished changes)',
|
||||
},
|
||||
altButtonEdit: {
|
||||
id: 'course-authoring.course-outline.card.button.edit.alt',
|
||||
defaultMessage: 'Edit',
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
export const ITEM_BADGE_STATUS = /** @type {const} */ ({
|
||||
live: 'live',
|
||||
publishedNotLive: 'published_not_live',
|
||||
unpublishedChanges: 'unpublished_changes',
|
||||
staffOnly: 'staff_only',
|
||||
draft: 'draft',
|
||||
});
|
||||
|
||||
export const STAFF_ONLY = 'staff_only';
|
||||
|
||||
export const HIGHLIGHTS_FIELD_MAX_LENGTH = 250;
|
||||
|
||||
export const CHECKLIST_FILTERS = /** @type {const} */ ({
|
||||
|
||||
@@ -51,10 +51,7 @@ const SectionCard = ({
|
||||
displayName,
|
||||
hasChanges,
|
||||
published,
|
||||
releasedToStudents,
|
||||
visibleToStaffOnly = false,
|
||||
visibilityState,
|
||||
staffOnlyMessage,
|
||||
highlights,
|
||||
actions,
|
||||
isHeaderVisible = true,
|
||||
@@ -63,10 +60,8 @@ const SectionCard = ({
|
||||
|
||||
const sectionStatus = getItemStatus({
|
||||
published,
|
||||
releasedToStudents,
|
||||
visibleToStaffOnly,
|
||||
visibilityState,
|
||||
staffOnlyMessage,
|
||||
hasChanges,
|
||||
});
|
||||
|
||||
const handleExpandContent = () => {
|
||||
@@ -110,7 +105,7 @@ const SectionCard = ({
|
||||
>
|
||||
<BaseTitleWithStatusBadge
|
||||
title={displayName}
|
||||
status={sectionStatus}
|
||||
status=""
|
||||
namePrefix={namePrefix}
|
||||
/>
|
||||
</TitleButton>
|
||||
@@ -190,10 +185,7 @@ SectionCard.propTypes = {
|
||||
displayName: PropTypes.string.isRequired,
|
||||
published: PropTypes.bool.isRequired,
|
||||
hasChanges: PropTypes.bool.isRequired,
|
||||
releasedToStudents: PropTypes.bool.isRequired,
|
||||
visibleToStaffOnly: PropTypes.bool,
|
||||
visibilityState: PropTypes.string.isRequired,
|
||||
staffOnlyMessage: PropTypes.bool.isRequired,
|
||||
highlights: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
shouldScroll: PropTypes.bool,
|
||||
explanatoryMessage: PropTypes.string,
|
||||
|
||||
@@ -10,7 +10,6 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
|
||||
import initializeStore from '../../store';
|
||||
import SectionCard from './SectionCard';
|
||||
import cardHeaderMessages from '../card-header/messages';
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
let axiosMock;
|
||||
@@ -20,10 +19,7 @@ const section = {
|
||||
id: '123',
|
||||
displayName: 'Section Name',
|
||||
published: true,
|
||||
releasedToStudents: true,
|
||||
visibleToStaffOnly: false,
|
||||
visibilityState: 'visible',
|
||||
staffOnlyMessage: false,
|
||||
visibilityState: 'live',
|
||||
hasChanges: false,
|
||||
highlights: ['highlight 1', 'highlight 2'],
|
||||
actions: {
|
||||
@@ -111,53 +107,6 @@ describe('<SectionCard />', () => {
|
||||
expect(onEditSectionSubmit).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders live status', async () => {
|
||||
const { findByText } = renderComponent();
|
||||
expect(await findByText(cardHeaderMessages.statusBadgeLive.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders published but live status', async () => {
|
||||
const { findByText } = renderComponent({
|
||||
section: {
|
||||
...section,
|
||||
published: true,
|
||||
releasedToStudents: false,
|
||||
visibleToStaffOnly: false,
|
||||
visibilityState: 'visible',
|
||||
staffOnlyMessage: false,
|
||||
},
|
||||
});
|
||||
expect(await findByText(cardHeaderMessages.statusBadgePublishedNotLive.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders staff status', async () => {
|
||||
const { findByText } = renderComponent({
|
||||
section: {
|
||||
...section,
|
||||
published: false,
|
||||
releasedToStudents: false,
|
||||
visibleToStaffOnly: true,
|
||||
visibilityState: 'staff_only',
|
||||
staffOnlyMessage: true,
|
||||
},
|
||||
});
|
||||
expect(await findByText(cardHeaderMessages.statusBadgeStaffOnly.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders draft status', async () => {
|
||||
const { findByText } = renderComponent({
|
||||
section: {
|
||||
...section,
|
||||
published: false,
|
||||
releasedToStudents: false,
|
||||
visibleToStaffOnly: false,
|
||||
visibilityState: 'staff_only',
|
||||
staffOnlyMessage: false,
|
||||
},
|
||||
});
|
||||
expect(await findByText(cardHeaderMessages.statusBadgeDraft.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('hides header based on isHeaderVisible flag', async () => {
|
||||
const { queryByTestId } = renderComponent({
|
||||
section: {
|
||||
|
||||
@@ -35,10 +35,7 @@ const SubsectionCard = ({
|
||||
displayName,
|
||||
hasChanges,
|
||||
published,
|
||||
releasedToStudents,
|
||||
visibleToStaffOnly = false,
|
||||
visibilityState,
|
||||
staffOnlyMessage,
|
||||
actions,
|
||||
isHeaderVisible = true,
|
||||
} = subsection;
|
||||
@@ -46,10 +43,8 @@ const SubsectionCard = ({
|
||||
const [isExpanded, setIsExpanded] = useState(!isHeaderVisible);
|
||||
const subsectionStatus = getItemStatus({
|
||||
published,
|
||||
releasedToStudents,
|
||||
visibleToStaffOnly,
|
||||
visibilityState,
|
||||
staffOnlyMessage,
|
||||
hasChanges,
|
||||
});
|
||||
|
||||
const handleExpandContent = () => {
|
||||
@@ -154,10 +149,7 @@ SubsectionCard.propTypes = {
|
||||
displayName: PropTypes.string.isRequired,
|
||||
published: PropTypes.bool.isRequired,
|
||||
hasChanges: PropTypes.bool.isRequired,
|
||||
releasedToStudents: PropTypes.bool.isRequired,
|
||||
visibleToStaffOnly: PropTypes.bool,
|
||||
visibilityState: PropTypes.string.isRequired,
|
||||
staffOnlyMessage: PropTypes.bool.isRequired,
|
||||
shouldScroll: PropTypes.bool,
|
||||
}).isRequired,
|
||||
subsection: PropTypes.shape({
|
||||
@@ -165,10 +157,7 @@ SubsectionCard.propTypes = {
|
||||
displayName: PropTypes.string.isRequired,
|
||||
published: PropTypes.bool.isRequired,
|
||||
hasChanges: PropTypes.bool.isRequired,
|
||||
releasedToStudents: PropTypes.bool.isRequired,
|
||||
visibleToStaffOnly: PropTypes.bool,
|
||||
visibilityState: PropTypes.string.isRequired,
|
||||
staffOnlyMessage: PropTypes.bool.isRequired,
|
||||
shouldScroll: PropTypes.bool,
|
||||
actions: PropTypes.shape({
|
||||
deletable: PropTypes.bool.isRequired,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
|
||||
import initializeStore from '../../store';
|
||||
import SubsectionCard from './SubsectionCard';
|
||||
import cardHeaderMessages from '../card-header/messages';
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
let axiosMock;
|
||||
@@ -19,10 +20,7 @@ const section = {
|
||||
id: '123',
|
||||
displayName: 'Section Name',
|
||||
published: true,
|
||||
releasedToStudents: true,
|
||||
visibleToStaffOnly: false,
|
||||
visibilityState: 'visible',
|
||||
staffOnlyMessage: false,
|
||||
visibilityState: 'live',
|
||||
hasChanges: false,
|
||||
highlights: ['highlight 1', 'highlight 2'],
|
||||
};
|
||||
@@ -31,10 +29,7 @@ const subsection = {
|
||||
id: '123',
|
||||
displayName: 'Subsection Name',
|
||||
published: true,
|
||||
releasedToStudents: true,
|
||||
visibleToStaffOnly: false,
|
||||
visibilityState: 'visible',
|
||||
staffOnlyMessage: false,
|
||||
visibilityState: 'live',
|
||||
hasChanges: false,
|
||||
actions: {
|
||||
draggable: true,
|
||||
@@ -161,4 +156,42 @@ describe('<SubsectionCard />', () => {
|
||||
expect(within(element).queryByTestId('subsection-card-header__menu-delete-button')).not.toBeInTheDocument();
|
||||
expect(queryByTestId('new-unit-button')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders live status', async () => {
|
||||
const { findByText } = renderComponent();
|
||||
expect(await findByText(cardHeaderMessages.statusBadgeLive.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders published but live status', async () => {
|
||||
const { findByText } = renderComponent({
|
||||
subsection: {
|
||||
...subsection,
|
||||
published: true,
|
||||
visibilityState: 'ready',
|
||||
},
|
||||
});
|
||||
expect(await findByText(cardHeaderMessages.statusBadgePublishedNotLive.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders staff status', async () => {
|
||||
const { findByText } = renderComponent({
|
||||
subsection: {
|
||||
...subsection,
|
||||
published: false,
|
||||
visibilityState: 'staff_only',
|
||||
},
|
||||
});
|
||||
expect(await findByText(cardHeaderMessages.statusBadgeStaffOnly.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders draft status', async () => {
|
||||
const { findByText } = renderComponent({
|
||||
subsection: {
|
||||
...subsection,
|
||||
published: false,
|
||||
visibilityState: 'needs_attention',
|
||||
},
|
||||
});
|
||||
expect(await findByText(cardHeaderMessages.statusBadgeDraft.defaultMessage)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,20 +31,15 @@ const UnitCard = ({
|
||||
displayName,
|
||||
hasChanges,
|
||||
published,
|
||||
releasedToStudents,
|
||||
visibleToStaffOnly = false,
|
||||
visibilityState,
|
||||
staffOnlyMessage,
|
||||
actions,
|
||||
isHeaderVisible = true,
|
||||
} = unit;
|
||||
|
||||
const unitStatus = getItemStatus({
|
||||
published,
|
||||
releasedToStudents,
|
||||
visibleToStaffOnly,
|
||||
visibilityState,
|
||||
staffOnlyMessage,
|
||||
hasChanges,
|
||||
});
|
||||
|
||||
const handleClickMenuButton = () => {
|
||||
@@ -124,10 +119,7 @@ UnitCard.propTypes = {
|
||||
displayName: PropTypes.string.isRequired,
|
||||
published: PropTypes.bool.isRequired,
|
||||
hasChanges: PropTypes.bool.isRequired,
|
||||
releasedToStudents: PropTypes.bool.isRequired,
|
||||
visibleToStaffOnly: PropTypes.bool,
|
||||
visibilityState: PropTypes.string.isRequired,
|
||||
staffOnlyMessage: PropTypes.bool.isRequired,
|
||||
shouldScroll: PropTypes.bool,
|
||||
actions: PropTypes.shape({
|
||||
deletable: PropTypes.bool.isRequired,
|
||||
@@ -142,10 +134,7 @@ UnitCard.propTypes = {
|
||||
displayName: PropTypes.string.isRequired,
|
||||
published: PropTypes.bool.isRequired,
|
||||
hasChanges: PropTypes.bool.isRequired,
|
||||
releasedToStudents: PropTypes.bool.isRequired,
|
||||
visibleToStaffOnly: PropTypes.bool,
|
||||
visibilityState: PropTypes.string.isRequired,
|
||||
staffOnlyMessage: PropTypes.bool.isRequired,
|
||||
shouldScroll: PropTypes.bool,
|
||||
}).isRequired,
|
||||
section: PropTypes.shape({
|
||||
@@ -153,10 +142,7 @@ UnitCard.propTypes = {
|
||||
displayName: PropTypes.string.isRequired,
|
||||
published: PropTypes.bool.isRequired,
|
||||
hasChanges: PropTypes.bool.isRequired,
|
||||
releasedToStudents: PropTypes.bool.isRequired,
|
||||
visibleToStaffOnly: PropTypes.bool,
|
||||
visibilityState: PropTypes.string.isRequired,
|
||||
staffOnlyMessage: PropTypes.bool.isRequired,
|
||||
shouldScroll: PropTypes.bool,
|
||||
}).isRequired,
|
||||
onOpenPublishModal: PropTypes.func.isRequired,
|
||||
|
||||
@@ -19,10 +19,7 @@ const section = {
|
||||
id: '1',
|
||||
displayName: 'Section Name',
|
||||
published: true,
|
||||
releasedToStudents: true,
|
||||
visibleToStaffOnly: false,
|
||||
visibilityState: 'visible',
|
||||
staffOnlyMessage: false,
|
||||
visibilityState: 'live',
|
||||
hasChanges: false,
|
||||
highlights: ['highlight 1', 'highlight 2'],
|
||||
};
|
||||
@@ -31,10 +28,7 @@ const subsection = {
|
||||
id: '12',
|
||||
displayName: 'Subsection Name',
|
||||
published: true,
|
||||
releasedToStudents: true,
|
||||
visibleToStaffOnly: false,
|
||||
visibilityState: 'visible',
|
||||
staffOnlyMessage: false,
|
||||
visibilityState: 'live',
|
||||
hasChanges: false,
|
||||
};
|
||||
|
||||
@@ -42,10 +36,7 @@ const unit = {
|
||||
id: '123',
|
||||
displayName: 'unit Name',
|
||||
published: true,
|
||||
releasedToStudents: true,
|
||||
visibleToStaffOnly: false,
|
||||
visibilityState: 'visible',
|
||||
staffOnlyMessage: false,
|
||||
visibilityState: 'live',
|
||||
hasChanges: false,
|
||||
actions: {
|
||||
draggable: true,
|
||||
|
||||
@@ -4,35 +4,31 @@ import {
|
||||
EditOutline as EditOutlineIcon,
|
||||
} from '@edx/paragon/icons';
|
||||
|
||||
import { ITEM_BADGE_STATUS, STAFF_ONLY, VIDEO_SHARING_OPTIONS } from './constants';
|
||||
import { ITEM_BADGE_STATUS, VIDEO_SHARING_OPTIONS } from './constants';
|
||||
import { VisibilityTypes } from '../data/constants';
|
||||
|
||||
/**
|
||||
* Get section status depended on section info
|
||||
* @param {bool} published - value from section info
|
||||
* @param {bool} releasedToStudents - value from section info
|
||||
* @param {bool} visibleToStaffOnly - value from section info
|
||||
* @param {string} visibilityState - value from section info
|
||||
* @param {bool} staffOnlyMessage - value from section info
|
||||
* @returns {ITEM_BADGE_STATUS[keyof ITEM_BADGE_STATUS]}
|
||||
*/
|
||||
const getItemStatus = ({
|
||||
published,
|
||||
releasedToStudents,
|
||||
visibleToStaffOnly,
|
||||
visibilityState,
|
||||
staffOnlyMessage,
|
||||
hasChanges,
|
||||
}) => {
|
||||
switch (true) {
|
||||
case published && releasedToStudents:
|
||||
return ITEM_BADGE_STATUS.live;
|
||||
case published && !releasedToStudents:
|
||||
return ITEM_BADGE_STATUS.publishedNotLive;
|
||||
case visibleToStaffOnly && staffOnlyMessage && visibilityState === STAFF_ONLY:
|
||||
case visibilityState === VisibilityTypes.STAFF_ONLY:
|
||||
return ITEM_BADGE_STATUS.staffOnly;
|
||||
case !published:
|
||||
return ITEM_BADGE_STATUS.draft;
|
||||
case visibilityState === VisibilityTypes.LIVE:
|
||||
return ITEM_BADGE_STATUS.live;
|
||||
case published && !hasChanges:
|
||||
return ITEM_BADGE_STATUS.publishedNotLive;
|
||||
case published && hasChanges:
|
||||
return ITEM_BADGE_STATUS.unpublishedChanges;
|
||||
default:
|
||||
return '';
|
||||
return ITEM_BADGE_STATUS.draft;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -61,6 +57,11 @@ const getItemStatusBadgeContent = (status, messages, intl) => {
|
||||
badgeTitle: intl.formatMessage(messages.statusBadgeStaffOnly),
|
||||
badgeIcon: LockIcon,
|
||||
};
|
||||
case ITEM_BADGE_STATUS.unpublishedChanges:
|
||||
return {
|
||||
badgeTitle: intl.formatMessage(messages.statusBadgeUnpublishedChanges),
|
||||
badgeIcon: EditOutlineIcon,
|
||||
};
|
||||
case ITEM_BADGE_STATUS.draft:
|
||||
return {
|
||||
badgeTitle: intl.formatMessage(messages.statusBadgeDraft),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* @readonly
|
||||
* @enum {string}
|
||||
*/
|
||||
export const RequestStatus = {
|
||||
export const RequestStatus = /** @type {const} */ ({
|
||||
IN_PROGRESS: 'in-progress',
|
||||
SUCCESSFUL: 'successful',
|
||||
FAILED: 'failed',
|
||||
@@ -14,36 +14,37 @@ export const RequestStatus = {
|
||||
CLEAR: 'clear',
|
||||
PARTIAL: 'partial',
|
||||
NOT_FOUND: 'not-found',
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Team sizes enum
|
||||
* @enum
|
||||
* @type {{MIN: number, MAX: number, DEFAULT: number}}
|
||||
*/
|
||||
export const TeamSizes = {
|
||||
export const TeamSizes = /** @type {const} */ ({
|
||||
DEFAULT: 5,
|
||||
MIN: 1,
|
||||
MAX: 500,
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Group types enum
|
||||
* @enum
|
||||
* @type {{PRIVATE_MANAGED: string, PUBLIC_MANAGED: string, OPEN: string}}
|
||||
*/
|
||||
export const GroupTypes = {
|
||||
export const GroupTypes = /** @type {const} */ ({
|
||||
OPEN: 'open',
|
||||
PUBLIC_MANAGED: 'public_managed',
|
||||
PRIVATE_MANAGED: 'private_managed',
|
||||
};
|
||||
});
|
||||
|
||||
export const DivisionSchemes = {
|
||||
export const DivisionSchemes = /** @type {const} */ ({
|
||||
NONE: 'none',
|
||||
COHORT: 'cohort',
|
||||
};
|
||||
});
|
||||
|
||||
export const VisibilityTypes = {
|
||||
export const VisibilityTypes = /** @type {const} */ ({
|
||||
LIVE: 'live',
|
||||
STAFF_ONLY: 'staff_only',
|
||||
HIDE_AFTER_DUE: 'hide_after_due',
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user