Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lk/submission actions #43

Merged
merged 13 commits into from
Sep 22, 2023
19 changes: 19 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Routes, Route } from 'react-router-dom';
import { ErrorPage } from '@edx/frontend-platform/react';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Spinner } from '@edx/paragon';

import { useIsORAConfigLoaded, useIsPageDataLoaded } from 'data/services/lms/hooks/selectors';

import PeerAssessmentView from 'views/PeerAssessmentView';
import SelfAssessmentView from 'views/SelfAssessmentView';
Expand All @@ -12,6 +15,22 @@ import routes from './routes';
const RouterRoot = () => {
const { formatMessage } = useIntl();

const isConfigLoaded = useIsORAConfigLoaded();
const isPageLoaded = useIsPageDataLoaded();

if (!isConfigLoaded || !isPageLoaded) {
return (
<div className="h-screen d-flex justify-content-center align-items-center">
<Spinner
animation="border"
variant="primary"
className="mr-3 spinner-md"
screenReaderText="loading"
/>
</div>
);
}

return (
<Routes>
<Route path={routes.peerAssessment} element={<PeerAssessmentView />} />
Expand Down
27 changes: 27 additions & 0 deletions src/components/FileUpload/ActionCell.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { IconButton, Icon } from '@edx/paragon';

import { useIntl } from '@edx/frontend-platform/i18n';
import { Delete, Preview } from '@edx/paragon/icons';

import messages from './messages';

const ActionCell = () => {
const { formatMessage } = useIntl();
return (
<>
<IconButton
src={Delete}
alt={formatMessage(messages.deleteButtonAltText)}
iconAs={Icon}
/>
<IconButton
src={Preview}
alt={formatMessage(messages.previewButtonAltText)}
iconAs={Icon}
/>
</>
);
};

export default ActionCell;
9 changes: 9 additions & 0 deletions src/components/FileUpload/ActionCell.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { shallow } from '@edx/react-unit-test-utils';
import ActionCell from './ActionCell';

describe('<ActionCell />', () => {
it('renders', () => {
const wrapper = shallow(<ActionCell />);
expect(wrapper.snapshot).toMatchSnapshot();
});
});
1 change: 0 additions & 1 deletion src/components/FileUpload/FileMetaDisplay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import messages from './messages';

const FileMetaDisplay = ({ name, description, size }) => (
<>
{console.log({ name, description, size })}
<div className="file-meta-option">
<strong><FormattedMessage {...messages.filePopoverNameTitle} /></strong>
<br />
Expand Down
94 changes: 94 additions & 0 deletions src/components/FileUpload/UploadConfirmModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React from 'react';
import PropTypes from 'prop-types';

import {
Form, FormLabel, ModalDialog, Button, ActionRow,
} from '@edx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
import messages from './messages';
import { useUploadConfirmModalHooks } from './hooks';

const UploadConfirmModal = ({
open, files, closeHandler, uploadHandler,
}) => {
const { formatMessage } = useIntl();

const {
errors, exitHandler, confirmUploadClickHandler, onFileDescriptionChange,
} = useUploadConfirmModalHooks({
files,
closeHandler,
uploadHandler,
});

return (
<ModalDialog
isOpen={open}
title={formatMessage(messages.uploadFileModalTitle)}
hasCloseButton={false}
onClose={exitHandler}
>
<ModalDialog.Header>
<ModalDialog.Title>
{formatMessage(messages.uploadFileModalTitle)}
</ModalDialog.Title>
</ModalDialog.Header>

<ModalDialog.Body>
<div>
{files.map((file, i) => (
// eslint-disable-next-line react/no-array-index-key
<Form.Group key={i}>
<FormLabel>
<strong>
{formatMessage(messages.uploadFileDescriptionFieldLabel)}
</strong>
<span className="file-name-ellipsis">{file.name}</span>
</FormLabel>
<Form.Control
isInvalid={errors[i]}
name={`file-${i}-description`}
onChange={onFileDescriptionChange(file)}
/>
{errors[i] && (
<Form.Control.Feedback type="invalid">
{errors[i] && formatMessage(messages.fileDescriptionMissingError)}
</Form.Control.Feedback>
)}
</Form.Group>
))}
</div>
</ModalDialog.Body>
<ModalDialog.Footer>
<ActionRow>
<ModalDialog.CloseButton variant="tertiary" onClick={exitHandler}>
{formatMessage(messages.cancelUploadFileButton)}
</ModalDialog.CloseButton>
<Button variant="primary" onClick={confirmUploadClickHandler}>
{formatMessage(messages.confirmUploadFileButton)}
</Button>
</ActionRow>
</ModalDialog.Footer>
</ModalDialog>
);
};

UploadConfirmModal.defaultProps = {
open: false,
files: [],
closeHandler: () => {},
uploadHandler: () => {},
};
UploadConfirmModal.propTypes = {
open: PropTypes.bool,
files: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string,
description: PropTypes.string,
}),
),
closeHandler: PropTypes.func,
uploadHandler: PropTypes.func,
};

export default UploadConfirmModal;
57 changes: 57 additions & 0 deletions src/components/FileUpload/UploadConfirmModal.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { shallow } from '@edx/react-unit-test-utils';
import UploadConfirmModal from './UploadConfirmModal';

import { useUploadConfirmModalHooks } from './hooks';

jest.mock('./hooks', () => ({
useUploadConfirmModalHooks: jest.fn(),
}));

describe('<UploadConfirmModal />', () => {
const props = {
open: true,
files: [],
closeHandler: jest.fn().mockName('closeHandler'),
uploadHandler: jest.fn().mockName('uploadHandler'),
};

const mockHooks = (overrides) => {
useUploadConfirmModalHooks.mockReturnValueOnce({
errors: [],
exitHandler: jest.fn().mockName('exitHandler'),
confirmUploadClickHandler: jest.fn().mockName('confirmUploadClickHandler'),
onFileDescriptionChange: () => jest.fn().mockName('onFileDescriptionChange'),
...overrides,
});
};
describe('renders', () => {
test('no files', () => {
mockHooks();
const wrapper = shallow(<UploadConfirmModal {...props} />);
expect(wrapper.snapshot).toMatchSnapshot();

expect(wrapper.instance.findByType('Form.Group').length).toBe(0);
});

test('multiple files', () => {
mockHooks(
{ errors: new Array(2) },
);
const wrapper = shallow(<UploadConfirmModal {...props} files={[{ name: 'file1' }, { name: 'file2' }]} />);
expect(wrapper.snapshot).toMatchSnapshot();

expect(wrapper.instance.findByType('Form.Group').length).toBe(2);
expect(wrapper.instance.findByType('Form.Control.Feedback').length).toBe(0);
});

test('with errors', () => {
mockHooks({ errors: [true, false] });
const wrapper = shallow(<UploadConfirmModal {...props} files={[{ name: 'file1' }, { name: 'file2' }]} />);
// wrapper.setState({ errors: [true, false] });
expect(wrapper.snapshot).toMatchSnapshot();

expect(wrapper.instance.findByType('Form.Group').length).toBe(2);
expect(wrapper.instance.findByType('Form.Control.Feedback').length).toBe(1);
});
});
});
16 changes: 16 additions & 0 deletions src/components/FileUpload/__snapshots__/ActionCell.test.jsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<ActionCell /> renders 1`] = `
<Fragment>
<IconButton
alt="Delete"
iconAs="Icon"
src={[Function]}
/>
<IconButton
alt="Preview"
iconAs="Icon"
src={[Function]}
/>
</Fragment>
`;
Loading
Loading