Skip to content

Commit

Permalink
fix: adding typescript config to admin portal (#988)
Browse files Browse the repository at this point in the history
* fix: draft commit for typescript changes

* fix: lint fixes

* fix: more test fixes

* fix: adding more lint fixes

* fix: PR requests

* fix: small logic change
  • Loading branch information
kiram15 committed Jun 8, 2023
1 parent 53b3d39 commit 3dc6e8b
Show file tree
Hide file tree
Showing 68 changed files with 13,599 additions and 8,225 deletions.
21 changes: 20 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,26 @@ const config = getBaseConfig('eslint');
/* Custom config manipulations */
config.rules = {
...config.rules,
'default-param-last': 'off',
'@typescript-eslint/default-param-last': 'off',
'react/require-default-props': 'off',
'import/no-named-as-default': 0,
};

config.ignorePatterns = ["*.json", ".eslintrc.js", "*.config.js", "jsdom-with-global.js"];

config.overrides = [
{
files: ['*.test.js', '*.test.jsx'],
parser: "@typescript-eslint/parser",
parserOptions: {
project: [
"./tsconfig.json",
"./functions/tsconfig.json",
]
}
},
];



module.exports = config;
2 changes: 1 addition & 1 deletion __mocks__/react-instantsearch-dom.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const MockReactInstantSearch = jest.genMockFromModule(
'react-instantsearch-dom',
);

// eslint-disable-next-line camelcase
// eslint-disable-next-line @typescript-eslint/naming-convention
const advertised_course_run = {
start: '2020-09-09T04:00:00Z',
key: 'course-v1:edX+Bee101+3T2020',
Expand Down
18,705 changes: 12,147 additions & 6,558 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
"scripts": {
"build": "fedx-scripts webpack",
"build:with-theme": "THEME=npm:@edx/brand-edx.org@latest npm run install-theme && fedx-scripts webpack",
"lint": "fedx-scripts eslint --ext .js --ext .jsx .",
"lint:fix": "fedx-scripts eslint --fix --ext .js --ext .jsx .",
"check-types": "tsc --noemit",
"lint": "fedx-scripts eslint --ext .js --ext .jsx .; npm run check-types",
"lint:fix": "fedx-scripts eslint --fix --ext .js --ext .jsx --ext .tsx --ext .ts .",
"precommit": "npm run lint",
"prepublishOnly": "npm run build",
"install-theme": "npm install \"@edx/brand@${THEME}\" --no-save",
Expand Down Expand Up @@ -90,7 +91,7 @@
},
"devDependencies": {
"@edx/browserslist-config": "1.0.0",
"@edx/frontend-build": "^12.5.0",
"@edx/frontend-build": "^12.9.0-alpha.1",
"@faker-js/faker": "^7.6.0",
"@testing-library/dom": "7.31.2",
"@testing-library/jest-dom": "5.11.9",
Expand All @@ -110,4 +111,4 @@
"resize-observer-polyfill": "1.5.1",
"ts-jest": "^26.5.0"
}
}
}
2 changes: 1 addition & 1 deletion src/components/Admin/SubscriptionDetailPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useSubscriptionFromParams } from '../subscriptions/data/contextHooks';
import SubscriptionDetailsSkeleton from '../subscriptions/SubscriptionDetailsSkeleton';
import { LPR_SUBSCRIPTION_PAGE_SIZE } from '../subscriptions/data/constants';

// eslint-disable-next-line no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const SubscriptionDetailPage = ({ enterpriseSlug, match }) => {
const [subscription, loadingSubscription] = useSubscriptionFromParams({ match });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ describe('CodeAssignmentModal component', () => {
expect(screen.getByText(initialProps.title)).toBeInTheDocument();
});
it('displays an error', () => {
// eslint-disable-next-line global-require, no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-unused-vars, global-require
const { Field } = require('redux-form');
const error = 'Errors ahoy!';
const props = { ...initialProps, error: [error], submitFailed: true };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,44 +25,6 @@ const selectColumn = {
disableSortBy: true,
};

const HighlightStepperSelectContent = ({ enterpriseId }) => {
const { setCurrentSelectedRowIds } = useContentHighlightsContext();
const currentSelectedRowIds = useContextSelector(
ContentHighlightsContext,
v => v[0].stepperModal.currentSelectedRowIds,
);
const searchClient = useContextSelector(
ContentHighlightsContext,
v => v[0].searchClient,
);
// TODO: replace testEnterpriseId with enterpriseId before push,
// uncomment out import and replace with testEnterpriseId to test
const searchFilters = `enterprise_customer_uuids:${ENABLE_TESTING(enterpriseId)}`;

return (
<SearchData>
<InstantSearch
indexName={configuration.ALGOLIA.INDEX_NAME}
searchClient={searchClient}
>
<Configure
filters={searchFilters}
hitsPerPage={MAX_PAGE_SIZE}
/>
<SearchHeader variant="default" />
<HighlightStepperSelectContentDataTable
selectedRowIds={currentSelectedRowIds}
onSelectedRowsChanged={setCurrentSelectedRowIds}
/>
</InstantSearch>
</SearchData>
);
};

HighlightStepperSelectContent.propTypes = {
enterpriseId: PropTypes.string.isRequired,
};

const PriceTableCell = ({ row }) => {
const contentPrice = row.original.firstEnrollablePaidSeatPrice;
if (!contentPrice) {
Expand Down Expand Up @@ -176,4 +138,42 @@ BaseHighlightStepperSelectContentDataTable.defaultProps = {

const HighlightStepperSelectContentDataTable = connectStateResults(BaseHighlightStepperSelectContentDataTable);

const HighlightStepperSelectContent = ({ enterpriseId }) => {
const { setCurrentSelectedRowIds } = useContentHighlightsContext();
const currentSelectedRowIds = useContextSelector(
ContentHighlightsContext,
v => v[0].stepperModal.currentSelectedRowIds,
);
const searchClient = useContextSelector(
ContentHighlightsContext,
v => v[0].searchClient,
);
// TODO: replace testEnterpriseId with enterpriseId before push,
// uncomment out import and replace with testEnterpriseId to test
const searchFilters = `enterprise_customer_uuids:${ENABLE_TESTING(enterpriseId)}`;

return (
<SearchData>
<InstantSearch
indexName={configuration.ALGOLIA.INDEX_NAME}
searchClient={searchClient}
>
<Configure
filters={searchFilters}
hitsPerPage={MAX_PAGE_SIZE}
/>
<SearchHeader variant="default" />
<HighlightStepperSelectContentDataTable
selectedRowIds={currentSelectedRowIds}
onSelectedRowsChanged={setCurrentSelectedRowIds}
/>
</InstantSearch>
</SearchData>
);
};

HighlightStepperSelectContent.propTypes = {
enterpriseId: PropTypes.string.isRequired,
};

export default HighlightStepperSelectContent;
2 changes: 1 addition & 1 deletion src/components/ContentHighlights/data/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export const LEARNER_PORTAL_CATALOG_VISIBILITY = {
export const DEFAULT_ERROR_MESSAGE = {
EMPTY_HIGHLIGHT_SET: 'There is no highlighted content for this highlight collection.',
// eslint-disable-next-line quotes
EMPTY_SELECTEDROWIDS: `You don't have any highlighted content selected. Go back to the previous step to select content.`,
EMPTY_SELECTEDROWIDS: 'You don\'t have any highlighted content selected. Go back to the previous step to select content.',
EXCEEDS_HIGHLIGHT_TITLE_LENGTH: `Titles may only be ${MAX_HIGHLIGHT_TITLE_LENGTH} characters or less`,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ jest.mock('react-router-dom', () => ({
useParams: jest.fn(),
}));

/* eslint-disable react/prop-types */
// eslint-disable-next-line no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ContentHighlightSetWrapper = (
enterpriseAppContextValue = initialEnterpriseAppContextValue,
{ children },
Expand Down
16 changes: 8 additions & 8 deletions src/components/NotFoundPage/index.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
import React from 'react';
import Helmet from 'react-helmet';

const NotFoundPage = () => (
<main role="main">
<div className="container-fluid mt-3">
<NotFound />
</div>
</main>
);

export const NotFound = () => (
<>
<Helmet>
Expand All @@ -22,4 +14,12 @@ export const NotFound = () => (
</>
);

const NotFoundPage = () => (
<main role="main">
<div className="container-fluid mt-3">
<NotFound />
</div>
</main>
);

export default NotFoundPage;
14 changes: 10 additions & 4 deletions src/components/forms/FormContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import React, { createContext, useContext, Context, ReactNode, Dispatch } from "react";
import type { FormActionArguments } from "./data/actions";
import type { FormWorkflowStep } from "./FormWorkflow";
import React, {
Context, Dispatch, createContext, ReactNode, useContext, useMemo,
} from 'react';

import type { FormActionArguments } from './data/actions';
import type { FormWorkflowStep } from './FormWorkflow';

export type FormFields = { [name: string]: any };
export type FormValidatorResult = boolean | string;
Expand Down Expand Up @@ -39,8 +42,11 @@ const FormContextProvider = ({
dispatch,
formContext,
}: FormContextProps) => {
const memoValue = useMemo(() => (
{ ...formContext, dispatch }
), [formContext, dispatch]);
return (
<FormContextObject.Provider value={{ ...formContext, dispatch }}>
<FormContextObject.Provider value={memoValue}>
{children}
</FormContextObject.Provider>
);
Expand Down
48 changes: 22 additions & 26 deletions src/components/forms/FormContextWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,42 @@
import React, { useReducer } from "react";
// @ts-ignore
import FormContextProvider from "./FormContext.tsx";
import type { FormFields } from "./FormContext";
// @ts-ignore
import FormWorkflow from "./FormWorkflow.tsx";
import type { FormWorkflowProps } from "./FormWorkflow";
// @ts-ignore
import {FormReducer, initializeForm } from "./data/reducer.ts";
import type { FormActionArguments } from "./data/actions";
import React, { useReducer } from 'react';
import FormContextProvider from './FormContext';
import FormWorkflow, { FormWorkflowProps } from './FormWorkflow';
import {
FormReducer, FormReducerType, initializeForm, InitializeFormArguments,
} from './data/reducer';

// Context wrapper for multi-step form container
function FormContextWrapper<FormData>({
type FormWrapperProps<FormConfigData> = FormWorkflowProps<FormConfigData> & { formData: FormConfigData };

const FormContextWrapper = <FormConfigData extends unknown>({
formWorkflowConfig,
onClickOut,
onSubmit,
formData,
isStepperOpen,
}: FormWorkflowProps<FormData>) {
}: FormWrapperProps<FormConfigData>) => {
const initializeAction: InitializeFormArguments<FormConfigData> = {
formFields: formData as FormConfigData,
currentStep: formWorkflowConfig.getCurrentStep(),
};
const [formFieldsState, dispatch] = useReducer<
FormReducer,
FormActionArguments
FormReducerType,
InitializeFormArguments<FormConfigData>
>(
FormReducer,
initializeForm(
{},
{
formFields: formData as FormFields,
currentStep: formWorkflowConfig.getCurrentStep(),
}
),
initializeForm
initializeAction,
initializeForm,
);
return (
<FormContextProvider
dispatch={dispatch}
formContext={formFieldsState || {}}
>
<FormWorkflow
{...{ formWorkflowConfig, onClickOut, onSubmit, isStepperOpen, dispatch }}
{...{
formWorkflowConfig, onClickOut, isStepperOpen, dispatch,
}}
/>
</FormContextProvider>
);
}
};

export default FormContextWrapper;
14 changes: 6 additions & 8 deletions src/components/forms/FormWaitModal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from "react";
import { AlertModal, Spinner } from "@edx/paragon";
// @ts-ignore
import { useFormContext } from "./FormContext.tsx";
import type { FormContext } from "./FormContext";
import React from 'react';
import { AlertModal, Spinner } from '@edx/paragon';
import { useFormContext } from './FormContext';
import type { FormContext } from './FormContext';

type FormWaitModal = {
type FormWaitModalProps = {
// FormContext state that when truthy, shows the modal
triggerState: string;
onClose: () => void;
Expand All @@ -18,9 +17,8 @@ const FormWaitModal = ({
onClose,
header,
text,
}: FormWaitModal) => {
}: FormWaitModalProps) => {
const { stateMap }: FormContext = useFormContext();

const isOpen = stateMap && stateMap[triggerState];

return (
Expand Down
Loading

0 comments on commit 3dc6e8b

Please sign in to comment.