Skip to content

Commit

Permalink
Merge branch 'master' into faisal/add-dependabot-file
Browse files Browse the repository at this point in the history
  • Loading branch information
brian-smith-tcril authored Dec 9, 2024
2 parents a89efac + 31ce540 commit 78ffa56
Show file tree
Hide file tree
Showing 28 changed files with 848 additions and 852 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup Nodejs Env
run: echo "NODE_VER=`cat .nvmrc`" >> $GITHUB_ENV
- name: Setup Nodejs
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VER }}
node-version-file: '.nvmrc'
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Lint
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18
20
2 changes: 1 addition & 1 deletion catalog-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ metadata:
annotations:
openedx.org/arch-interest-groups: ""
spec:
owner: group:frontend-all
owner: "group:committers-frontend"
type: "library"
lifecycle: "experimental"
1,160 changes: 444 additions & 716 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"dependencies": {
"@edx/brand": "npm:@edx/brand-edx.org@2.1.3",
"@edx/frontend-lib-special-exams": "^3.1.0",
"@edx/frontend-platform": "8.1.1",
"@edx/frontend-platform": "8.1.2",
"@edx/openedx-atlas": "^0.6.0",
"@edx/react-unit-test-utils": "^3.0.0",
"@edx/tinymce-language-selector": "1.1.0",
Expand All @@ -53,7 +53,7 @@
"@zip.js/zip.js": "^2.7.30",
"axios": "^1.5.1",
"classnames": "^2.3.2",
"core-js": "3.38.1",
"core-js": "3.39.0",
"file-saver": "^2.0.5",
"filesize": "^8.0.6",
"jest-when": "^3.6.0",
Expand All @@ -65,8 +65,8 @@
"react-dom": "^17.0.2",
"react-pdf": "^7.4.0",
"react-redux": "7.2.9",
"react-router": "6.26.1",
"react-router-dom": "6.26.1",
"react-router": "6.28.0",
"react-router-dom": "6.28.0",
"redux": "4.2.1",
"redux-devtools-extension": "^2.13.9",
"redux-logger": "^3.0.6",
Expand All @@ -76,11 +76,11 @@
},
"devDependencies": {
"@edx/browserslist-config": "^1.1.1",
"@openedx/frontend-build": "14.1.0",
"@openedx/frontend-build": "14.2.0",
"@edx/reactifex": "^2.1.1",
"@testing-library/dom": "^10.0.0",
"@testing-library/jest-dom": "6.4.6",
"@testing-library/react": "16.0.0",
"@testing-library/dom": "^9.3.3",
"@testing-library/jest-dom": "5.17.0",
"@testing-library/react": "12.1.5",
"@testing-library/user-event": "^14.5.1",
"glob": "7.2.3",
"husky": "7.0.4",
Expand Down
91 changes: 52 additions & 39 deletions src/components/FileUpload/__snapshots__/index.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`<FileUpload /> render default 1`] = `
<div>
<h3>
File upload
</h3>
<b>
Uploaded files
Expand Down Expand Up @@ -57,20 +58,23 @@ exports[`<FileUpload /> render default 1`] = `
]
}
/>
<Dropzone
accept={
{
"*": [
".pdf",
".jpg",
],
<Form.Group
isInValid={true}
>
<Dropzone
accept={
{
"*": [
".pdf",
".jpg",
],
}
}
}
maxSize={123456}
multiple={true}
onProcessUpload={[MockFunction onProcessUpload]}
progressVariant="bar"
/>
maxSize={123456}
onProcessUpload={[MockFunction onProcessUpload]}
progressVariant="bar"
/>
</Form.Group>
</div>
`;

Expand All @@ -82,6 +86,7 @@ exports[`<FileUpload /> render extra columns when activeStepName is submission 1
<div>
<h3>
File upload
</h3>
<b>
Uploaded files
Expand Down Expand Up @@ -140,27 +145,31 @@ exports[`<FileUpload /> render extra columns when activeStepName is submission 1
]
}
/>
<Dropzone
accept={
{
"*": [
".pdf",
".jpg",
],
<Form.Group
isInValid={true}
>
<Dropzone
accept={
{
"*": [
".pdf",
".jpg",
],
}
}
}
maxSize={123456}
multiple={true}
onProcessUpload={[MockFunction onProcessUpload]}
progressVariant="bar"
/>
maxSize={123456}
onProcessUpload={[MockFunction onProcessUpload]}
progressVariant="bar"
/>
</Form.Group>
</div>
`;

exports[`<FileUpload /> render without dropzone and confirm modal when isReadOnly 1`] = `
<div>
<h3>
File upload
</h3>
<FilePreview
defaultCollapsePreview={false}
Expand Down Expand Up @@ -224,6 +233,7 @@ exports[`<FileUpload /> render without file preview if uploadedFiles are empty a
<div>
<h3>
File upload
</h3>
<b>
Uploaded files
Expand Down Expand Up @@ -312,20 +322,23 @@ exports[`<FileUpload /> render without header 1`] = `
]
}
/>
<Dropzone
accept={
{
"*": [
".pdf",
".jpg",
],
<Form.Group
isInValid={true}
>
<Dropzone
accept={
{
"*": [
".pdf",
".jpg",
],
}
}
}
maxSize={123456}
multiple={true}
onProcessUpload={[MockFunction onProcessUpload]}
progressVariant="bar"
/>
maxSize={123456}
onProcessUpload={[MockFunction onProcessUpload]}
progressVariant="bar"
/>
</Form.Group>
</div>
`;

Expand Down
29 changes: 17 additions & 12 deletions src/components/FileUpload/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import filesize from 'filesize';

import { DataTable, Dropzone } from '@openedx/paragon';
import { DataTable, Dropzone, Form } from '@openedx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';

import { nullMethod } from 'utils';
Expand Down Expand Up @@ -35,6 +35,7 @@ const FileUpload = ({
onDeletedFile,
defaultCollapsePreview,
hideHeader,
isInValid,
}) => {
const { formatMessage } = useIntl();
const {
Expand All @@ -47,7 +48,7 @@ const FileUpload = ({
const viewStep = useViewStep();
const activeStepName = useActiveStepName();
const {
enabled, fileUploadLimit, allowedExtensions, maxFileSize,
enabled, fileUploadLimit, allowedExtensions, maxFileSize, required,
} = useFileUploadConfig() || {};

if (!enabled || viewStep === stepNames.studentTraining) {
Expand Down Expand Up @@ -78,7 +79,7 @@ const FileUpload = ({

return (
<div>
{!hideHeader && <h3>{formatMessage(messages.fileUploadTitle)}</h3>}
{!hideHeader && <h3>{formatMessage(messages.fileUploadTitle)} {required && <span>(required)</span>}</h3>}
{uploadedFiles.length > 0 && isReadOnly && (
<FilePreview defaultCollapsePreview={defaultCollapsePreview} />
)}
Expand All @@ -93,15 +94,17 @@ const FileUpload = ({
columns={columns}
/>
{!isReadOnly && fileUploadLimit > uploadedFiles.length && (
<Dropzone
multiple
onProcessUpload={onProcessUpload}
progressVariant="bar"
accept={{
'*': (allowedExtensions || []).map((ext) => `.${ext}`),
}}
maxSize={maxFileSize}
/>
<Form.Group isInValid>
<Dropzone
onProcessUpload={onProcessUpload}
progressVariant="bar"
accept={{
'*': (allowedExtensions || []).map((ext) => `.${ext}`),
}}
maxSize={maxFileSize}
/>
{isInValid && <Form.Control.Feedback type="invalid">{formatMessage(messages.required)}</Form.Control.Feedback>}
</Form.Group>
)}
{!isReadOnly && isModalOpen && (
<UploadConfirmModal
Expand All @@ -122,6 +125,7 @@ FileUpload.defaultProps = {
onDeletedFile: nullMethod,
defaultCollapsePreview: false,
hideHeader: false,
isInValid: false,
};
FileUpload.propTypes = {
isReadOnly: PropTypes.bool,
Expand All @@ -137,6 +141,7 @@ FileUpload.propTypes = {
onDeletedFile: PropTypes.func,
defaultCollapsePreview: PropTypes.bool,
hideHeader: PropTypes.bool,
isInValid: PropTypes.bool,
};

export default FileUpload;
5 changes: 5 additions & 0 deletions src/components/FileUpload/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ const messages = defineMessages({
defaultMessage: 'File description',
description: 'Popover title for file description',
},
required: {
id: 'frontend-app-ora.FileUpload.required',
defaultMessage: 'File Upload is required',
description: 'Indicating file upload is required',
},
});

export default messages;
2 changes: 2 additions & 0 deletions src/data/services/lms/types/blockInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface TextResponseConfig {
optional: boolean,
editorType: 'text' | 'tinymce',
allowLatexPreview: boolean,
required: boolean,
}

export interface FileResponseConfig {
Expand All @@ -27,6 +28,7 @@ export interface FileResponseConfig {
allowedExtensions: string[],
blockedExtensions: string[],
fileTypeDescription: string,
required: boolean,
}

export interface SubmissionConfig {
Expand Down
8 changes: 6 additions & 2 deletions src/hooks/actions/useConfirmAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ export const assessmentSteps = [
stepNames.peer,
];

const useConfirmAction = () => {
const useConfirmAction = (validateBeforeOpen = () => true) => {
const [isOpen, setIsOpen] = useKeyedState(stateKeys.isOpen, false);
const close = React.useCallback(() => setIsOpen(false), [setIsOpen]);
const open = React.useCallback(() => setIsOpen(true), [setIsOpen]);
const open = React.useCallback(() => {
if (validateBeforeOpen()) {
setIsOpen(true);
}
}, [setIsOpen, validateBeforeOpen]);
return React.useCallback((config) => {
const { description, title } = config;
const action = config.action.action ? config.action.action : config.action;
Expand Down
14 changes: 8 additions & 6 deletions src/hooks/actions/useConfirmAction.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ const nestedActionConfig = {
action: { action: config.action },
};

const validateBeforeOpen = jest.fn(() => true);

let out;
describe('useConfirmAction', () => {
beforeEach(() => {
jest.clearAllMocks();
state.mock();
out = useConfirmAction();
out = useConfirmAction(validateBeforeOpen);
});
afterEach(() => { state.resetVals(); });
describe('behavior', () => {
Expand All @@ -44,7 +46,7 @@ describe('useConfirmAction', () => {
state.expectSetStateCalledWith(stateKeys.isOpen, false);
};
const testOpen = (openFn) => {
expect(openFn.useCallback.prereqs).toEqual([state.setState[stateKeys.isOpen]]);
expect(openFn.useCallback.prereqs).toEqual([state.setState[stateKeys.isOpen], validateBeforeOpen]);
openFn.useCallback.cb();
state.expectSetStateCalledWith(stateKeys.isOpen, true);
};
Expand All @@ -62,13 +64,13 @@ describe('useConfirmAction', () => {
expect(out.useCallback.prereqs[1]).toEqual(true);
});
test('open callback', () => {
out = useConfirmAction();
out = useConfirmAction(validateBeforeOpen);
testOpen(prereqs[2]);
});
});
describe('callback', () => {
it('returns action with labels from config action', () => {
out = useConfirmAction().useCallback.cb(config);
out = useConfirmAction(validateBeforeOpen).useCallback.cb(config);
testOpen(out.action.onClick);
expect(out.action.children).toEqual(config.action.labels.default);
expect(out.confirmProps.isOpen).toEqual(false);
Expand All @@ -78,7 +80,7 @@ describe('useConfirmAction', () => {
testClose(out.confirmProps.close);
});
it('returns nested action from config action', () => {
out = useConfirmAction().useCallback.cb(nestedActionConfig);
out = useConfirmAction(validateBeforeOpen).useCallback.cb(nestedActionConfig);
testOpen(out.action.onClick);
expect(out.action.children).toEqual(nestedActionConfig.action.action.labels.default);
expect(out.confirmProps.isOpen).toEqual(false);
Expand All @@ -89,7 +91,7 @@ describe('useConfirmAction', () => {
});
it('returns action with children from config action', () => {
state.mockVals({ [stateKeys.isOpen]: true });
out = useConfirmAction().useCallback.cb(noLabelConfig);
out = useConfirmAction(validateBeforeOpen).useCallback.cb(noLabelConfig);
testOpen(out.action.onClick);
expect(out.action.children).toEqual(noLabelConfig.action.children);
expect(out.confirmProps.isOpen).toEqual(true);
Expand Down
Loading

0 comments on commit 78ffa56

Please sign in to comment.