{"version":3,"sources":["store/subjectOutline/types.ts","store/subjectOutline/reducer.ts","store/index.ts","components/Header/Header.tsx","exceptions/SubjectOutlinesError.ts","store/subjectOutline/actions.ts","components/Navigation/Navigation.tsx","components/EmbeddedOutline/EmbeddedOutline.tsx","components/ErrorPanel/ErrorPanel.tsx","components/OutlineList/OutlineListItem.tsx","components/OutlineList/OutlineList.tsx","components/StaffAlert/StaffAlert.tsx","components/Home/Home.tsx","App.tsx","index.tsx","configureStore.ts"],"names":["LocationStrings","AttendModeStrings","SubjectOutlineActionEnum","SubjectOutline","so","studyPackageCode","session","sessionName","year","location","attendanceMode","url","published","this","initialState","isLoading","navigationShouldDisplay","outlines","publishedOutlines","unpublishedOutlines","subjectOutlineReducer","state","action","type","FETCH_REQUEST","FETCH_SUCCESS","data","map","o","filter","FETCH_ERROR","errors","message","SELECT","undefined","selected","length","combineReducers","subjectOutline","mapStateToProps","Header","Heading","level","margin","generateHeadingText","props","locationName","attendance","attendanceModeName","suffix","Component","connect","SubjectOutlinesError","status","Error","SubjectOutlinesActions","dispatch","a","async","getState","document","getElementsByTagName","href","fetch","credentials","res","json","err","console","error","statusText","Navigation","View","as","textAlign","Button","variant","onClick","goBack","bind","icon","IconArrowOpenStartSolid","clearSubjectOutline","EmbeddedOutline","isMobile","isChrome","isFirefox","className","src","outline","parameterisedUrl","title","download","target","rel","ErrorPanel","Billboard","hero","IconTroubleLine","size","heading","OutlineListItem","fluidWidth","clickFunc","index","Flex","justifyItems","Item","shouldGrow","IconWarningLine","Text","OutlineList","ensureDataFetched","fetchSubjectOutlines","i","selectSubjectOutline","renderOutlines","Spinner","renderTitle","role","key","selectOutline","StaffAlert","Alert","renderCloseButtonLabel","onDismiss","storeDismissal","localStorage","setItem","Home","match","params","renderStaff","renderDefault","dismissed","getItem","App","store","history","path","exact","component","theme","use","baseUrl","getAttribute","createBrowserHistory","basename","middleware","thunk","routerMiddleware","enhancers","rootReducer","router","connectRouter","createStore","compose","applyMiddleware","configureStore","window","initialReduxState","rootElement","getElementById","ReactDOM","render","CookiesProvider"],"mappings":"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","file":"static/js/main.1decdcb3.chunk.js","sourcesContent":["export interface ISubjectOutline {\r\n studyPackageCode: string;\r\n session: string;\r\n sessionName: string;\r\n year: string;\r\n location: string;\r\n attendanceMode: string;\r\n url: string;\r\n published: boolean;\r\n}\r\n\r\nexport interface IProblemDetail {\r\n status: number;\r\n title: string;\r\n detail: string;\r\n}\r\n\r\nenum LocationStrings {\r\n U = \"City\",\r\n CN = \"China\",\r\n HK = \"Hong Kong\",\r\n SG = \"Singapore\"\r\n}\r\n\r\nenum AttendModeStrings {\r\n INT = \"Standard mode\",\r\n EXT = \"Distance mode\",\r\n BLC = \"Block mode\"\r\n}\r\n\r\nexport class SubjectOutline {\r\n public get locationName() {\r\n return LocationStrings[this.location as keyof typeof LocationStrings];\r\n }\r\n\r\n public get attendanceModeName() {\r\n return AttendModeStrings[this.attendanceMode as keyof typeof AttendModeStrings];\r\n }\r\n\r\n public get parameterisedUrl() {\r\n return `${this.url}#view=FitH`;\r\n }\r\n\r\n public studyPackageCode: string;\r\n public session: string;\r\n public sessionName: string;\r\n public year: string;\r\n public location: string;\r\n public attendanceMode: string;\r\n public url: string;\r\n public published: boolean;\r\n\r\n constructor(so: ISubjectOutline) {\r\n this.studyPackageCode = so.studyPackageCode;\r\n this.session = so.session;\r\n this.sessionName = so.sessionName;\r\n this.year = so.year;\r\n this.location = so.location;\r\n this.attendanceMode = so.attendanceMode;\r\n this.url = so.url;\r\n this.published = so.published;\r\n }\r\n}\r\n\r\nexport type ApiResponse = ISubjectOutline[];\r\n\r\nexport enum SubjectOutlineActionEnum {\r\n FETCH_REQUEST = \"SUBJECT_OUTLINE_FETCH_REQUEST\",\r\n FETCH_SUCCESS = \"SUBJECT_OUTLINE_FETCH_SUCCESS\",\r\n FETCH_ERROR = \"SUBJECT_OUTLINE_FETCH_ERROR\",\r\n SELECT = \"SUBJECT_OUTLINE_SELECTED\"\r\n}\r\n\r\nexport interface ISubjectOutlineState {\r\n isLoading: boolean;\r\n outlines: SubjectOutline[];\r\n publishedOutlines: SubjectOutline[];\r\n unpublishedOutlines: SubjectOutline[];\r\n selected?: SubjectOutline;\r\n errors?: string;\r\n navigationShouldDisplay: boolean;\r\n}\r\n\r\ninterface IFetchRequestAction {\r\n type: typeof SubjectOutlineActionEnum.FETCH_REQUEST;\r\n}\r\n\r\ninterface IFetchSuccessAction {\r\n type: typeof SubjectOutlineActionEnum.FETCH_SUCCESS;\r\n data: ISubjectOutline[];\r\n}\r\n\r\ninterface IFetchErrorAction {\r\n type: typeof SubjectOutlineActionEnum.FETCH_ERROR;\r\n data: Error;\r\n}\r\n\r\ninterface ISelectSubjectOutlineAction {\r\n type: typeof SubjectOutlineActionEnum.SELECT;\r\n selected: number | undefined;\r\n}\r\n\r\nexport type SubjectOutlineActionTypes =\r\n | IFetchRequestAction\r\n | IFetchSuccessAction\r\n | IFetchErrorAction\r\n | ISelectSubjectOutlineAction;\r\n","import {\r\n ISubjectOutlineState,\r\n SubjectOutline,\r\n SubjectOutlineActionEnum,\r\n SubjectOutlineActionTypes,\r\n} from \"./types\";\r\n\r\nconst initialState: ISubjectOutlineState = {\r\n isLoading: false,\r\n navigationShouldDisplay: false,\r\n outlines: [],\r\n publishedOutlines: [],\r\n unpublishedOutlines: []\r\n};\r\n\r\nexport function subjectOutlineReducer(\r\n state = initialState,\r\n action: SubjectOutlineActionTypes,\r\n): ISubjectOutlineState {\r\n switch (action.type) {\r\n case SubjectOutlineActionEnum.FETCH_REQUEST:\r\n return { ...state, isLoading: true };\r\n case SubjectOutlineActionEnum.FETCH_SUCCESS:\r\n const outlines = action.data.map((o) => new SubjectOutline(o));\r\n return {\r\n ...state,\r\n isLoading: false,\r\n outlines,\r\n publishedOutlines: outlines.filter((o) => o.published),\r\n unpublishedOutlines: outlines.filter((o) => !o.published)\r\n };\r\n case SubjectOutlineActionEnum.FETCH_ERROR:\r\n return { ...state, isLoading: false, errors: action.data.message };\r\n case SubjectOutlineActionEnum.SELECT:\r\n return action.selected !== undefined\r\n ? {\r\n ...state,\r\n isLoading: false,\r\n navigationShouldDisplay: state.outlines.length > 1,\r\n selected: state.outlines[action.selected],\r\n }\r\n : {\r\n ...state,\r\n isLoading: false,\r\n navigationShouldDisplay: false,\r\n selected: undefined,\r\n };\r\n default:\r\n return state;\r\n }\r\n}\r\n","import { combineReducers } from \"redux\";\r\nimport { subjectOutlineReducer } from \"./subjectOutline/reducer\";\r\n\r\nconst rootReducer = combineReducers({\r\n subjectOutline: subjectOutlineReducer,\r\n});\r\n\r\nexport type AppState = ReturnType;\r\n\r\nexport const mapStateToProps = ({ subjectOutline }: AppState) => ({\r\n ...subjectOutline,\r\n});\r\n","import React, { Component } from \"react\";\r\nimport { connect } from \"react-redux\";\r\n\r\nimport { Heading } from \"@instructure/ui-heading\";\r\n\r\nimport { mapStateToProps } from \"../../store\";\r\nimport { ISubjectOutlineState } from \"../../store/subjectOutline/types\";\r\n\r\ntype AllProps = ISubjectOutlineState;\r\n\r\nclass Header extends Component {\r\n public render() {\r\n return (\r\n \r\n {this.generateHeadingText()}\r\n \r\n );\r\n }\r\n private generateHeadingText() {\r\n if (this.props.selected || this.props.outlines.length === 1) {\r\n const o = this.props.selected || this.props.outlines[0];\r\n\r\n const location = o.location !== \"U\" ? o.locationName : null;\r\n const attendance = o.attendanceMode !== \"INT\" ? o.attendanceModeName : null;\r\n\r\n let suffix = \"\";\r\n if (location && attendance) {\r\n suffix = `(${location}, ${attendance})`;\r\n } else if (location) {\r\n suffix = `(${location})`;\r\n } else if (attendance) {\r\n suffix = `(${attendance})`;\r\n }\r\n // tslint:disable-next-line: max-line-length\r\n return `Subject Outline - ${o.studyPackageCode} ${o.year} ${o.sessionName} ${suffix}`;\r\n }\r\n\r\n return \"Subject Outlines\";\r\n }\r\n}\r\n\r\nexport default connect(mapStateToProps)(Header);\r\n","export default class SubjectOutlinesError extends Error {\r\n public status: number;\r\n public constructor(message: string, status: number) {\r\n super(message);\r\n\r\n this.status = status;\r\n }\r\n}","import { ActionCreator, Dispatch } from \"redux\";\r\nimport { ThunkAction } from \"redux-thunk\";\r\nimport { AppState } from \"..\";\r\nimport SubjectOutlinesError from \"../../exceptions/SubjectOutlinesError\";\r\nimport { ISubjectOutline, SubjectOutlineActionEnum, SubjectOutlineActionTypes } from \"./types\";\r\n\r\nexport type ThunkResult = ThunkAction;\r\n\r\nconst clearSubjectOutline: ActionCreator> = () => async (\r\n dispatch: Dispatch\r\n) => dispatch({ selected: undefined, type: SubjectOutlineActionEnum.SELECT });\r\n\r\nconst fetchSubjectOutlines: ActionCreator>> = () => async (\r\n dispatch: Dispatch,\r\n getState\r\n) => {\r\n if (\r\n getState().subjectOutline.isLoading ||\r\n getState().subjectOutline.errors ||\r\n getState().subjectOutline.outlines.length !== 0\r\n ) {\r\n return false;\r\n }\r\n\r\n dispatch({ type: SubjectOutlineActionEnum.FETCH_REQUEST });\r\n\r\n const url = `${document.getElementsByTagName(\"base\")[0].href}api/SubjectOutline`;\r\n const res = await fetch(url, { credentials: \"include\" });\r\n\r\n try {\r\n const data = await res.json();\r\n\r\n if (data.status) {\r\n const err = new SubjectOutlinesError(data.message, data.status);\r\n // tslint:disable-next-line: no-console\r\n console.error(err);\r\n dispatch({ data: err, type: SubjectOutlineActionEnum.FETCH_ERROR });\r\n return false;\r\n }\r\n\r\n dispatch({ data, type: SubjectOutlineActionEnum.FETCH_SUCCESS });\r\n return true;\r\n } catch (err) {\r\n // tslint:disable-next-line: no-console\r\n console.error(err);\r\n err.message = `An unhandled error has occurred: [${res.status}] ${res.statusText}.\\n\\nPlease send a ServiceConnect ticket to the Learning and Teaching Systems team.`;\r\n // tslint:disable-next-line: no-console\r\n console.error(err);\r\n dispatch({ data: err, type: SubjectOutlineActionEnum.FETCH_ERROR });\r\n return false;\r\n }\r\n};\r\n\r\nconst fetchSubjectOutlinesSuccess: ActionCreator> = (data: ISubjectOutline[]) => async (\r\n dispatch: Dispatch\r\n) => dispatch({ data, type: SubjectOutlineActionEnum.FETCH_SUCCESS });\r\n\r\nconst fetchSubjectOutlinesError: ActionCreator> = (data: Error) => async (\r\n dispatch: Dispatch\r\n) => dispatch({ data, type: SubjectOutlineActionEnum.FETCH_ERROR });\r\n\r\nconst selectSubjectOutline: ActionCreator> = (selected: number) => async (\r\n dispatch: Dispatch,\r\n getState\r\n) => dispatch({ selected, type: SubjectOutlineActionEnum.SELECT } as SubjectOutlineActionTypes);\r\n\r\nexport interface ISubjectOutlineActions {\r\n clearSubjectOutline: ActionCreator>;\r\n fetchSubjectOutlines: ActionCreator>>;\r\n fetchSubjectOutlinesSuccess: ActionCreator>;\r\n fetchSubjectOutlinesError: ActionCreator>;\r\n selectSubjectOutline: ActionCreator>;\r\n}\r\n\r\nexport const SubjectOutlinesActions: ISubjectOutlineActions = {\r\n clearSubjectOutline,\r\n fetchSubjectOutlines,\r\n fetchSubjectOutlinesError,\r\n fetchSubjectOutlinesSuccess,\r\n selectSubjectOutline\r\n};\r\n","import React, { Component } from \"react\";\r\nimport { connect } from \"react-redux\";\r\n\r\nimport { Button } from \"@instructure/ui-buttons\";\r\nimport { IconArrowOpenStartSolid } from \"@instructure/ui-icons\";\r\nimport { View } from \"@instructure/ui-layout\";\r\nimport { ActionCreator } from \"redux\";\r\nimport { ThunkDispatch } from \"redux-thunk\";\r\nimport { mapStateToProps } from \"../../store\";\r\nimport { SubjectOutlinesActions, ThunkResult } from \"../../store/subjectOutline/actions\";\r\nimport { ISubjectOutlineState } from \"../../store/subjectOutline/types\";\r\n\r\ninterface IDispatchProps {\r\n clearSubjectOutline: ActionCreator>;\r\n}\r\n\r\ntype AllProps = ISubjectOutlineState & IDispatchProps;\r\n\r\nclass Navigation extends Component {\r\n public render() {\r\n return this.props.navigationShouldDisplay ? (\r\n \r\n \r\n Back to Subject Outlines\r\n \r\n \r\n ) : null;\r\n }\r\n\r\n private goBack() {\r\n this.props.clearSubjectOutline();\r\n }\r\n}\r\n\r\nexport default connect(\r\n mapStateToProps,\r\n (dispatch: ThunkDispatch<{}, {}, any>) => ({\r\n clearSubjectOutline: () => dispatch(SubjectOutlinesActions.clearSubjectOutline()),\r\n }),\r\n)(Navigation);\r\n","import React, { Component } from \"react\";\r\nimport { isChrome, isFirefox, isMobile } from \"react-device-detect\";\r\nimport { SubjectOutline } from \"../../store/subjectOutline/types\";\r\n\r\ninterface IProps {\r\n outline: SubjectOutline;\r\n}\r\n\r\nexport default class EmbeddedOutline extends Component {\r\n public render() {\r\n const embed = !isMobile && (isChrome || isFirefox);\r\n return embed ? (\r\n \r\n ) : (\r\n \r\n Download your Subject Outline\r\n \r\n );\r\n }\r\n}\r\n","import React, { Component } from \"react\";\r\n\r\nimport { Billboard } from \"@instructure/ui-billboard\";\r\nimport { IconTroubleLine } from \"@instructure/ui-icons\";\r\nimport { connect } from \"react-redux\";\r\nimport { mapStateToProps } from \"../../store\";\r\nimport { ISubjectOutlineState } from \"../../store/subjectOutline/types\";\r\n\r\ntype AllProps = ISubjectOutlineState;\r\n\r\nclass ErrorPanel extends Component {\r\n public render() {\r\n const message = this.props.errors || \"No details provided\";\r\n return (\r\n }\r\n size=\"large\"\r\n as=\"div\"\r\n heading=\"Sorry, a technical error has occurred\"\r\n message={message}\r\n />\r\n );\r\n }\r\n}\r\n\r\nexport default connect(mapStateToProps)(ErrorPanel);\r\n","import { Button } from \"@instructure/ui-buttons\";\r\nimport { IconWarningLine } from \"@instructure/ui-icons\";\r\nimport { Flex } from \"@instructure/ui-layout\";\r\nimport { Text } from \"@instructure/ui-text\";\r\nimport React, { Component } from \"react\";\r\nimport { SubjectOutline } from \"../../store/subjectOutline/types\";\r\n\r\ninterface IProps {\r\n outline: SubjectOutline;\r\n index: number;\r\n clickFunc(i: number): void;\r\n}\r\n\r\nclass OutlineListItem extends Component {\r\n public render() {\r\n const o = this.props.outline;\r\n const location = o.location !== \"U\" ? o.locationName : null;\r\n const attendance = o.attendanceMode !== \"INT\" ? o.attendanceModeName : null;\r\n\r\n let suffix = \"\";\r\n if (location && attendance) {\r\n suffix = `(${location}, ${attendance})`;\r\n } else if (location) {\r\n suffix = `(${location})`;\r\n } else if (attendance) {\r\n suffix = `(${attendance})`;\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n Subject Outline - {o.studyPackageCode} {o.year} {o.sessionName} {location} {suffix}\r\n \r\n {!o.published ?\r\n \r\n Unpublished\r\n : false}\r\n \r\n \r\n );\r\n }\r\n}\r\n\r\nexport default OutlineListItem;\r\n","// Inst-UI components\r\nimport { View } from \"@instructure/ui-layout\";\r\nimport { Spinner } from \"@instructure/ui-spinner\";\r\n// React\r\nimport React, { Component } from \"react\";\r\nimport { connect } from \"react-redux\";\r\nimport { ActionCreator } from \"redux\";\r\nimport { ThunkDispatch } from \"redux-thunk\";\r\n// Store\r\nimport { mapStateToProps } from \"../../store\";\r\nimport { SubjectOutlinesActions, ThunkResult } from \"../../store/subjectOutline/actions\";\r\nimport { ISubjectOutlineState } from \"../../store/subjectOutline/types\";\r\n// Components\r\nimport EmbeddedOutline from \"../EmbeddedOutline/EmbeddedOutline\";\r\nimport ErrorPanel from \"../ErrorPanel/ErrorPanel\";\r\nimport OutlineListItem from \"./OutlineListItem\";\r\nimport \"./style.css\";\r\n\r\ninterface IDispatchActions {\r\n fetchSubjectOutlines: ActionCreator>;\r\n selectSubjectOutline: ActionCreator>;\r\n}\r\n\r\ntype AllProps = ISubjectOutlineState & IDispatchActions & { role?: string };\r\n\r\nclass OutlineList extends Component {\r\n public componentDidMount() {\r\n this.ensureDataFetched();\r\n }\r\n\r\n public componentDidUpdate() {\r\n this.ensureDataFetched();\r\n }\r\n\r\n public ensureDataFetched() {\r\n this.props.fetchSubjectOutlines();\r\n }\r\n\r\n public selectOutline(i: number) {\r\n this.props.selectSubjectOutline(i);\r\n }\r\n\r\n public render() {\r\n return (\r\n \r\n {this.renderOutlines()}\r\n \r\n );\r\n }\r\n\r\n private renderOutlines() {\r\n // Show error panel if an error was returned\r\n if (this.props.errors) {\r\n return ;\r\n }\r\n\r\n // Show the selected or only returned outline\r\n if (this.props.selected !== undefined || this.props.outlines.length === 1) {\r\n const outline = this.props.selected || this.props.outlines[0];\r\n return ;\r\n }\r\n\r\n // Show the loading spinner if still fetching\r\n if (this.props.isLoading) {\r\n return (\r\n \r\n );\r\n }\r\n\r\n if (this.props.role === \"student\") {\r\n if (this.props.publishedOutlines.length === 1) {\r\n const outline = this.props.publishedOutlines[0];\r\n return ;\r\n }\r\n\r\n return this.props.publishedOutlines.map((o, i) => (\r\n \r\n \r\n ));\r\n }\r\n\r\n return this.props.outlines.map((o, i) => (\r\n \r\n \r\n ));\r\n }\r\n}\r\n\r\nexport default connect(\r\n mapStateToProps,\r\n (dispatch: ThunkDispatch<{}, {}, any>) => ({\r\n fetchSubjectOutlines: () => dispatch(SubjectOutlinesActions.fetchSubjectOutlines()),\r\n selectSubjectOutline: (i: number) =>\r\n dispatch(SubjectOutlinesActions.selectSubjectOutline(i))\r\n }),\r\n)(OutlineList);\r\n","import { Alert } from \"@instructure/ui-alerts\";\r\nimport React, { Component } from \"react\";\r\n\r\n// tslint:disable: max-line-length\r\nclass StaffAlert extends Component {\r\n public render() {\r\n return (\r\n \r\n Note: Some Subject Outlines may be flagged as Unpublished.
\r\n Where possible, students will always see the published Subject Outline that best matches their enrolment, or a published Standard Subject Outline if one is available.
\r\n For more information, please refer to the Subject Outline guide.\r\n \r\n );\r\n }\r\n\r\n private storeDismissal() {\r\n localStorage.setItem(\"so-alert-dismissed\", \"true\");\r\n }\r\n}\r\n\r\nexport default StaffAlert;\r\n","// Inst-UI\r\nimport { View } from \"@instructure/ui-layout\";\r\n// React\r\nimport React, { Component } from \"react\";\r\nimport { RouteComponentProps } from \"react-router\";\r\n// Components\r\nimport Header from \"../Header/Header\";\r\nimport Navigation from \"../Navigation/Navigation\";\r\nimport OutlineList from \"../OutlineList/OutlineList\";\r\nimport StaffAlert from \"../StaffAlert/StaffAlert\";\r\n\r\ntype Props = RouteComponentProps<{ role: string }>;\r\n\r\nclass Home extends Component {\r\n public render() {\r\n return this.props.match.params.role === \"staff\" ? this.renderStaff() : this.renderDefault();\r\n }\r\n\r\n private renderStaff() {\r\n const dismissed = localStorage.getItem(\"so-alert-dismissed\");\r\n return (\r\n \r\n \r\n
\r\n {dismissed !== \"true\" ? : \"\"}\r\n \r\n \r\n );\r\n }\r\n\r\n private renderDefault() {\r\n return (\r\n \r\n \r\n
\r\n \r\n \r\n );\r\n }\r\n}\r\n\r\nexport default Home;\r\n","import { ConnectedRouter } from \"connected-react-router\";\r\nimport { History } from \"history\";\r\nimport React, { Component } from \"react\";\r\nimport { Provider } from \"react-redux\";\r\nimport { Route } from \"react-router\";\r\nimport { Store } from \"redux\";\r\nimport Home from \"./components/Home/Home\";\r\nimport { AppState } from \"./store\";\r\n\r\ninterface IAppProps {\r\n store: Store;\r\n history: History;\r\n}\r\n\r\nclass App extends Component {\r\n public render() {\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n }\r\n}\r\n\r\nexport default App;\r\n","// Inst-UI\r\nimport { theme } from \"@instructure/canvas-theme\";\r\n// Deps\r\nimport { createBrowserHistory } from \"history\";\r\nimport React from \"react\";\r\nimport { CookiesProvider } from \"react-cookie\";\r\nimport ReactDOM from \"react-dom\";\r\n// Components\r\nimport App from \"./App\";\r\n// Store\r\nimport { configureStore } from \"./configureStore\";\r\n\r\ntheme.use({});\r\n\r\nconst baseUrl: string = document.getElementsByTagName(\"base\")[0].getAttribute(\"href\")!;\r\nconst history = createBrowserHistory({ basename: baseUrl });\r\n\r\nconst initialState = (window as any).initialReduxState;\r\nconst store = configureStore(history, initialState);\r\n\r\nconst rootElement = document.getElementById(\"root\");\r\n\r\nReactDOM.render(, rootElement);\r\n","import { connectRouter, routerMiddleware } from \"connected-react-router\";\r\nimport { History } from \"history\";\r\nimport { applyMiddleware, combineReducers, compose, createStore } from \"redux\";\r\nimport thunk from \"redux-thunk\";\r\nimport { AppState } from \"./store\";\r\nimport { subjectOutlineReducer } from \"./store/subjectOutline/reducer\";\r\n\r\nexport function configureStore(history: History, initialState: AppState) {\r\n const middleware = [thunk, routerMiddleware(history)];\r\n\r\n const enhancers = [];\r\n const isDevelopment = process.env.NODE_ENV === \"development\";\r\n if (isDevelopment && typeof window !== \"undefined\" && (window as any).devTooolsExtension) {\r\n enhancers.push((window as any).devTooolsExtension());\r\n }\r\n\r\n const rootReducer = combineReducers({\r\n router: connectRouter(history),\r\n subjectOutline: subjectOutlineReducer,\r\n });\r\n\r\n return createStore(\r\n rootReducer,\r\n initialState,\r\n compose(\r\n applyMiddleware(...middleware),\r\n ...enhancers,\r\n ),\r\n );\r\n}\r\n"],"sourceRoot":""}