Skip to content

Commit

Permalink
feat: make placeholder depend on api response (#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
KristinAoki authored Jul 25, 2023
1 parent cc7fc6a commit 0e1a7e2
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 47 deletions.
2 changes: 0 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,9 @@ ENABLE_NEW_VIDEO_UPLOAD_PAGE = false
ENABLE_NEW_SCHEDULE_DETAILS_PAGE = false
ENABLE_NEW_GRADING_PAGE = false
ENABLE_NEW_COURSE_TEAM_PAGE = false
ENABLE_NEW_ADVANCED_SETTINGS_PAGE = false
ENABLE_NEW_IMPORT_PAGE = false
ENABLE_NEW_EXPORT_PAGE = false
ENABLE_UNIT_PAGE = false
ENABLE_NEW_CUSTOM_PAGES = false
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN = false
BBB_LEARN_MORE_URL=''
HOTJAR_APP_ID=''
Expand Down
2 changes: 0 additions & 2 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,9 @@ ENABLE_NEW_VIDEO_UPLOAD_PAGE = false
ENABLE_NEW_SCHEDULE_DETAILS_PAGE = false
ENABLE_NEW_GRADING_PAGE = false
ENABLE_NEW_COURSE_TEAM_PAGE = false
ENABLE_NEW_ADVANCED_SETTINGS_PAGE = true
ENABLE_NEW_IMPORT_PAGE = false
ENABLE_NEW_EXPORT_PAGE = false
ENABLE_UNIT_PAGE = false
ENABLE_NEW_CUSTOM_PAGES = true
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN = false
BBB_LEARN_MORE_URL=''
HOTJAR_APP_ID=''
Expand Down
2 changes: 0 additions & 2 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ ENABLE_NEW_VIDEO_UPLOAD_PAGE = true
ENABLE_NEW_SCHEDULE_DETAILS_PAGE = true
ENABLE_NEW_GRADING_PAGE = true
ENABLE_NEW_COURSE_TEAM_PAGE = true
ENABLE_NEW_ADVANCED_SETTINGS_PAGE = true
ENABLE_NEW_IMPORT_PAGE = true
ENABLE_NEW_EXPORT_PAGE = true
ENABLE_UNIT_PAGE = true
ENABLE_NEW_CUSTOM_PAGES = true
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN = true
BBB_LEARN_MORE_URL=''
10 changes: 2 additions & 8 deletions src/CourseAuthoringRoutes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ const CourseAuthoringRoutes = ({ courseId }) => {
<ProctoredExamSettings courseId={courseId} />
</PageRoute>
<PageRoute path={`${path}/custom-pages`}>
{process.env.ENABLE_NEW_CUSTOM_PAGES === 'true'
&& (
<CustomPages courseId={courseId} />
)}
<CustomPages courseId={courseId} />
</PageRoute>
<PageRoute path={`${path}/container/:blockId`}>
{process.env.ENABLE_UNIT_PAGE === 'true'
Expand Down Expand Up @@ -109,10 +106,7 @@ const CourseAuthoringRoutes = ({ courseId }) => {
)}
</PageRoute>
<PageRoute path={`${path}/settings/advanced`}>
{process.env.ENABLE_NEW_ADVANCED_SETTINGS_PAGE === 'true'
&& (
<AdvancedSettings courseId={courseId} />
)}
<AdvancedSettings courseId={courseId} />
</PageRoute>
<PageRoute path={`${path}/import`}>
{process.env.ENABLE_NEW_IMPORT_PAGE === 'true'
Expand Down
8 changes: 8 additions & 0 deletions src/advanced-settings/AdvancedSettings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from '@edx/paragon';
import { CheckCircle, Info, Warning } from '@edx/paragon/icons';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import Placeholder from '@edx/frontend-lib-content-components';

import AlertProctoringError from '../generic/AlertProctoringError';
import InternetConnectionAlert from '../generic/internet-connection-alert';
Expand Down Expand Up @@ -72,6 +73,13 @@ const AdvancedSettings = ({ intl, courseId }) => {
// eslint-disable-next-line react/jsx-no-useless-fragment
return <></>;
}
if (loadingSettingsStatus === RequestStatus.DENIED) {
return (
<div className="row justify-contnt-center m-6">
<Placeholder />
</div>
);
}

const handleSettingChange = (e, settingName) => {
const { value } = e.target;
Expand Down
6 changes: 5 additions & 1 deletion src/advanced-settings/data/thunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ export function fetchCourseAppSettings(courseId) {
dispatch(fetchCourseAppsSettingsSuccess(settingValues));
dispatch(updateLoadingStatus({ status: RequestStatus.SUCCESSFUL }));
} catch (error) {
dispatch(updateLoadingStatus({ status: RequestStatus.FAILED }));
if (error.response && error.response.status === 403) {
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.DENIED }));
} else {
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.FAILED }));
}
}
};
}
Expand Down
11 changes: 8 additions & 3 deletions src/custom-pages/CustomPages.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
ModalDialog,
} from '@edx/paragon';
import { Add, SpinnerSimple } from '@edx/paragon/icons';
import {
import Placeholder, {
DraggableList,
SortableItem,
ErrorAlert,
Expand Down Expand Up @@ -96,13 +96,18 @@ const CustomPages = ({
},
disabledStates: ['pending'],
};

useEffect(() => { setOrderedPages(pages); }, [customPagesIds, savingStatus]);
if (loadingStatus === RequestStatus.IN_PROGRESS) {
// eslint-disable-next-line react/jsx-no-useless-fragment
return (<></>);
}

if (loadingStatus === RequestStatus.DENIED) {
return (
<div data-testid="under-construction-placeholder" className="row justify-contnt-center m-6">
<Placeholder />
</div>
);
}
return (
<CustomPagesProvider courseId={courseId}>
<main className="container container-mw-xl p-4 pt-5">
Expand Down
20 changes: 13 additions & 7 deletions src/custom-pages/CustomPages.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import CustomPages from './CustomPages';
import {
generateFetchPageApiResponse,
generateNewPageApiResponse,
getStatusValue,
courseId,
initialState,
} from './factories/mockApiResponses';
Expand All @@ -45,12 +46,12 @@ const renderComponent = () => {
);
};

const mockStore = async () => {
const mockStore = async (status) => {
const xblockAddUrl = `${getApiBaseUrl()}/xblock/`;
const reorderUrl = `${getTabHandlerUrl(courseId)}/reorder`;
const fetchPagesUrl = `${getTabHandlerUrl(courseId)}`;

axiosMock.onGet(fetchPagesUrl).reply(200, generateFetchPageApiResponse());
axiosMock.onGet(fetchPagesUrl).reply(getStatusValue(status), generateFetchPageApiResponse());
axiosMock.onPost(reorderUrl).reply(204);
axiosMock.onPut(xblockAddUrl).reply(200, generateNewPageApiResponse());

Expand All @@ -72,21 +73,26 @@ describe('CustomPages', () => {
store = initializeStore(initialState);
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
});
it('should ', async () => {
renderComponent();
await mockStore(RequestStatus.DENIED);
expect(screen.getByTestId('under-construction-placeholder')).toBeVisible();
});
it('should have breadecrumbs', async () => {
renderComponent();
await mockStore();
await mockStore(RequestStatus.SUCCESSFUL);
expect(screen.getByLabelText('Custom Page breadcrumbs')).toBeVisible();
});
it('should contain header row with title, add button and view live button', async () => {
renderComponent();
await mockStore();
await mockStore(RequestStatus.SUCCESSFUL);
expect(screen.getByText(messages.heading.defaultMessage)).toBeVisible();
expect(screen.getByTestId('header-add-button')).toBeVisible();
expect(screen.getByTestId('header-view-live-button')).toBeVisible();
});
it('should add new page when "add a new page button" is clicked', async () => {
renderComponent();
await mockStore();
await mockStore(RequestStatus.SUCCESSFUL);
const addButton = screen.getByTestId('body-add-button');
expect(addButton).toBeVisible();
await act(async () => { fireEvent.click(addButton); });
Expand All @@ -95,7 +101,7 @@ describe('CustomPages', () => {
});
it('should open student view modal when "add a new page button" is clicked', async () => {
renderComponent();
await mockStore();
await mockStore(RequestStatus.SUCCESSFUL);
const viewButton = screen.getByTestId('student-view-example-button');
expect(viewButton).toBeVisible();
expect(screen.queryByLabelText(messages.studentViewModalTitle.defaultMessage)).toBeNull();
Expand All @@ -104,7 +110,7 @@ describe('CustomPages', () => {
});
it('should update page order on drag', async () => {
renderComponent();
await mockStore();
await mockStore(RequestStatus.SUCCESSFUL);
const buttons = await screen.queryAllByRole('button');
const draggableButton = buttons[9];
expect(draggableButton).toBeVisible();
Expand Down
1 change: 0 additions & 1 deletion src/custom-pages/data/slice.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const slice = createSlice({
savingStatus: '',
addingStatus: 'default',
deletingStatus: '',
customPagesApiStatus: {},
},
reducers: {
setPageIds: (state, { payload }) => {
Expand Down
5 changes: 3 additions & 2 deletions src/custom-pages/data/thunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ export function fetchCustomPages(courseId) {
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.SUCCESSFUL }));
} catch (error) {
if (error.response && error.response.status === 403) {
dispatch(updateCustomPagesApiStatus({ status: RequestStatus.DENIED }));
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.DENIED }));
} else {
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.FAILED }));
}
dispatch(updateLoadingStatus({ courseId, status: RequestStatus.FAILED }));
}
};
}
Expand Down
11 changes: 11 additions & 0 deletions src/custom-pages/factories/mockApiResponses.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { RequestStatus } from '../../data/constants';

export const courseId = 'course-v1:edX+DemoX+Demo_Course';

export const initialState = {
Expand Down Expand Up @@ -62,3 +64,12 @@ export const generateNewPageApiResponse = () => ({
locator: 'mOckID2',
courseKey: courseId,
});

export const getStatusValue = (status) => {
switch (status) {
case RequestStatus.DENIED:
return 403;
default:
return 200;
}
};
12 changes: 0 additions & 12 deletions src/pages-and-resources/pages/PageCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,6 @@ const PageCard = ({
// eslint-disable-next-line react/no-unstable-nested-components
const SettingsButton = () => {
if (page.legacyLink) {
if (process.env.ENABLE_NEW_CUSTOM_PAGES === 'true' && page.name === 'Custom pages') {
return (
<Hyperlink destination="custom-pages">
<IconButton
src={ArrowForward}
iconAs={Icon}
size="inline"
alt={intl.formatMessage(messages.settings)}
/>
</Hyperlink>
);
}
return (
<Hyperlink destination={page.legacyLink}>
<IconButton
Expand Down
5 changes: 0 additions & 5 deletions src/pages-and-resources/pages/PageCard.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@ describe('LiveSettings', () => {
renderComponent();
expect(queryAllByRole(container, 'button')).toHaveLength(3);
});
it('should navigate to custom-pages', async () => {
renderComponent();
const [customPagesSettingsButton] = queryAllByRole(container, 'link');
expect(customPagesSettingsButton).toHaveAttribute('href', 'custom-pages');
});
it('should navigate to legacyLink', async () => {
renderComponent();
const textbookSettingsButton = queryAllByRole(container, 'link')[1];
Expand Down
4 changes: 2 additions & 2 deletions src/studio-header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const Header = ({
<a rel="noopener" href={getPagePath(courseId, process.env.ENABLE_NEW_UPDATES_PAGE, 'course_info')}>{intl.formatMessage(messages['header.links.updates'])}</a>
</div>
<div className="mb-1 small">
<a rel="noopener" href={getPagePath(courseId, process.env.ENABLE_NEW_CUSTOM_PAGES, 'tabs')}>{intl.formatMessage(messages['header.links.pages'])}</a>
<a rel="noopener" href={getPagePath(courseId, 'true', 'tabs')}>{intl.formatMessage(messages['header.links.pages'])}</a>
</div>
<div className="mb-1 small">
<a rel="noopener" href={getPagePath(courseId, process.env.ENABLE_NEW_FILES_UPLOADS_PAGE, 'assets')}>{intl.formatMessage(messages['header.links.filesAndUploads'])}</a>
Expand Down Expand Up @@ -75,7 +75,7 @@ const Header = ({
<a rel="noopener" href={`${config.STUDIO_BASE_URL}/group_configurations/course-v1:${courseId}`}>{intl.formatMessage(messages['header.links.groupConfigurations'])}</a>
</div>
<div className="mb-1 small">
<a rel="noopener" href={getPagePath(courseId, process.env.ENABLE_NEW_ADVANCED_SETTINGS_PAGE, 'settings/advanced')}>{intl.formatMessage(messages['header.links.advancedSettings'])}</a>
<a rel="noopener" href={`${config.STUDIO_BASE_URL}/settings/advanced/${courseId}`}>{intl.formatMessage(messages['header.links.advancedSettings'])}</a>
</div>
<div className="mb-1 small">
<a rel="noopener" href={`${config.STUDIO_BASE_URL}/certificates/${courseId}`}>{intl.formatMessage(messages['header.links.certificates'])}</a>
Expand Down

0 comments on commit 0e1a7e2

Please sign in to comment.