diff --git a/waspc/data/Generator/templates/react-app/src/_Page.js b/waspc/data/Generator/templates/react-app/src/_Page.js deleted file mode 100644 index 19980e31b..000000000 --- a/waspc/data/Generator/templates/react-app/src/_Page.js +++ /dev/null @@ -1,46 +0,0 @@ -{{={= =}=}} -import React, { Component } from 'react' -import { connect } from 'react-redux' - -{=# jsImports =} -import {= what =} from "{= from =}" -{=/ jsImports =} - -{=# entities =} -import * as {= entityLowerName =}State from '{= entityStatePath =}' -import * as {= entityLowerName =}Actions from '{= entityActionsPath =}' -import {= entity.name =} from '{= entityClassPath =}' -{=# entityCreateForms =} -import {= entityForm.name =} from '{= path =}' -{=/ entityCreateForms =} -{=# entityLists =} -import {= entityList.name =} from '{= path =}' -{=/ entityLists =} -{=/ entities =} - -{=# pageStylePath =} -import '{= pageStylePath =}' -{=/ pageStylePath =} - - -export class {= page.name =} extends Component { - // TODO: Add propTypes. - - render() { - return ( - {=& page.content =} - ) - } -} - -export default connect(state => ({ -{=# entities =} - {= entityLowerName =}List: {= entityLowerName =}State.selectors.all(state) -{=/ entities =} -}), { -{=# entities =} - add{= entityUpperName =}: {= entityLowerName =}Actions.add, - update{= entityUpperName =}: {= entityLowerName =}Actions.update, - remove{= entityUpperName =}: {= entityLowerName =}Actions.remove -{=/ entities =} -})({= page.name =}) diff --git a/waspc/data/Generator/templates/react-app/src/entities/_entity/_Entity.js b/waspc/data/Generator/templates/react-app/src/entities/_entity/_Entity.js deleted file mode 100644 index 852dce035..000000000 --- a/waspc/data/Generator/templates/react-app/src/entities/_entity/_Entity.js +++ /dev/null @@ -1,29 +0,0 @@ -{{={= =}=}} -import uuidv4 from 'uuid/v4' - -export default class {= entityClassName =} { - _data = {} - - constructor (data = {}) { - this._data = { - id: data.id || uuidv4(), - {=# entity.fields =} - {= name =}: data.{= name =}, - {=/ entity.fields =} - } - } - - get id () { - return this._data.id - } - - {=# entity.fields =} - get {= name =} () { - return this._data.{= name =} - } - {=/ entity.fields =} - - toData () { - return this._data - } -} diff --git a/waspc/data/Generator/templates/react-app/src/entities/_entity/actionTypes.js b/waspc/data/Generator/templates/react-app/src/entities/_entity/actionTypes.js deleted file mode 100644 index 917ac07f4..000000000 --- a/waspc/data/Generator/templates/react-app/src/entities/_entity/actionTypes.js +++ /dev/null @@ -1,5 +0,0 @@ -{{={= =}=}} -export const ADD = 'entities/{= entityLowerName =}/ADD' -export const SET = 'entities/{= entityLowerName =}/SET' -export const UPDATE = 'entities/{= entityLowerName =}/UPDATE' -export const REMOVE = 'entities/{= entityLowerName =}/REMOVE' diff --git a/waspc/data/Generator/templates/react-app/src/entities/_entity/actions.js b/waspc/data/Generator/templates/react-app/src/entities/_entity/actions.js deleted file mode 100644 index 67327cca1..000000000 --- a/waspc/data/Generator/templates/react-app/src/entities/_entity/actions.js +++ /dev/null @@ -1,39 +0,0 @@ -{{={= =}=}} -import * as types from './actionTypes' -import {=entityClassName=} from './{=entityClassName=}' -import { selectors } from './state' - - -/** - * @param {{= entity.name =}} {= entityLowerName =} - */ -export const add = ({=_entity=}) => ({ - type: types.ADD, - data: {=_entity=}.toData() -}) - -/** - * @param {{=entityClassName=}[]} {=_entities=} - */ -export const set = ({=_entities=}) => ({ - type: types.SET, - {=_entities=}: {=_entities=}.map({=_e=} => {=_e=}.toData()) -}) - -/** - * @param {String} id - * @param {Object} data - Partial data that will be merged with existing {= entityLowerName =}. - */ -export const update = (id, data) => ({ - type: types.UPDATE, - id, - data -}) - -/** - * @param {String} id - */ -export const remove = (id) => ({ - type: types.REMOVE, - id -}) diff --git a/waspc/data/Generator/templates/react-app/src/entities/_entity/components/CreateForm.js b/waspc/data/Generator/templates/react-app/src/entities/_entity/components/CreateForm.js deleted file mode 100644 index 3295eaaee..000000000 --- a/waspc/data/Generator/templates/react-app/src/entities/_entity/components/CreateForm.js +++ /dev/null @@ -1,122 +0,0 @@ -{{={= =}=}} -import _ from 'lodash' -import React from 'react' -import PropTypes from 'prop-types' - -import FormControlLabel from '@material-ui/core/FormControlLabel' -import Switch from '@material-ui/core/Switch' -import Button from '@material-ui/core/Button' -import TextField from '@material-ui/core/TextField' - -import {= entityClassName =} from '../{= entityClassName =}' - - -export default class {= formName =} extends React.Component { - static propTypes = { - onCreate: PropTypes.func, - submitButtonLabel: PropTypes.string - } - - state = { - fields: { - {=# formFields =} - {=# boolean =} - {= name =}: {= defaultValue =}, - {=/ boolean =} - {=# string =} - {= name =}: '{= defaultValue =}', - {=/ string =} - {=/ formFields =} - } - } - - setField = (name, valueOrFn) => { - this.setState(prevState => ({ - fields: { - ...prevState.fields, - [name]: _.isFunction(valueOrFn) ? valueOrFn(prevState) : valueOrFn - } - })) - } - - resetAllFields = () => { - {=# formFields =} - {=# boolean =} - this.setField('{= name =}', {= defaultValue =}) - {=/ boolean =} - {=# string =} - this.setField('{= name =}', '{= defaultValue =}') - {=/ string =} - {=/ formFields =} - } - - toggleField = (name) => { - this.setField(name, prevState => !prevState.fields[name]) - } - - getField = (name) => { - return this.state.fields[name] - } - - handleSubmit = () => { - this.props.onCreate(new {= entityClassName =}(this.state.fields)) - this.resetAllFields() - } - - render() { - return ( -
-
- {=# formFields =} - {=# boolean =} - {=# show =} -
- this.toggleField('{= name =}')} - value="{= name =}" - /> - } - /> -
- {=/ show =} - {=/ boolean =} - {=# string =} - {=# show =} -
- this.setField('{= name =}', event.target.value)} - margin="normal" - fullWidth - InputLabelProps={{ - shrink: true - }} - /> -
- {=/ show =} - {=/ string =} - {=/ formFields =} - {=# showSubmitButton =} -
- -
- {=/ showSubmitButton =} -
-
- ) - } -} diff --git a/waspc/data/Generator/templates/react-app/src/entities/_entity/components/List.js b/waspc/data/Generator/templates/react-app/src/entities/_entity/components/List.js deleted file mode 100644 index 45c5f9144..000000000 --- a/waspc/data/Generator/templates/react-app/src/entities/_entity/components/List.js +++ /dev/null @@ -1,170 +0,0 @@ -{{={= =}=}} -import _ from 'lodash' -import React from 'react' -import PropTypes from 'prop-types' -import { connect } from 'react-redux' - -import Paper from '@material-ui/core/Paper' -import Table from '@material-ui/core/Table' -import TableBody from '@material-ui/core/TableBody' -import TableCell from '@material-ui/core/TableCell' -import TableHead from '@material-ui/core/TableHead' -import TableRow from '@material-ui/core/TableRow' -import Checkbox from '@material-ui/core/Checkbox' -import TextField from '@material-ui/core/TextField' -import ClickAwayListener from '@material-ui/core/ClickAwayListener' -{=# mutexFiltersConfig =} -import Select from '@material-ui/core/Select' -import MenuItem from '@material-ui/core/MenuItem' -{=/ mutexFiltersConfig =} - -import * as {= entityLowerName =}State from '../state' -import * as {= entityLowerName =}Actions from '../actions' - -import {= entityClassName =} from '../{= entityClassName =}' - - -export class {= listName =} extends React.Component { - static propTypes = { - editable: PropTypes.bool - } - - state = { - {= entityBeingEditedStateVar =}: null, - - {=# mutexFiltersConfig =} - filterName: '{= noFilterLabel =}' - {=/ mutexFiltersConfig =} - } - - setAsBeingEdited = {= entityLowerName =} => this.setState({ - {= entityBeingEditedStateVar =}: {= entityLowerName =}.id - }) - - isBeingEdited = {= entityLowerName =} => - {= entityLowerName =}.id === this.state.{= entityBeingEditedStateVar =} - - finishEditing = {= entityLowerName =} => { - if ({= entityLowerName =}.id === this.state.{= entityBeingEditedStateVar =}) - this.setState({ {= entityBeingEditedStateVar =}: null }) - } - - {=! Render "render" functions for each field, if provided =} - {=# listFields =} - {=# render =} - {= renderFnName =} = - {=& render =} - {=/ render =} - {=/ listFields =} - - {=# mutexFiltersConfig =} - handleFilterChange = event => { - this.setState({ filterName: event.target.value }) - } - - filters = { - {=# filters =} - '{= name =}': {=& predicate =}, - {=/ filters =} - } - {=/ mutexFiltersConfig =} - - render() { - {=# mutexFiltersConfig =} - const {= entitiesToShowRenderVar =} = this.state.filterName !== '{= noFilterLabel =}' ? - {=! TODO(matija): duplication, we could extract entityLowerName_List =} - this.props.{= entityLowerName =}List.filter(this.filters[this.state.filterName]) : - this.props.{= entityLowerName =}List - {=/ mutexFiltersConfig =} - - {=^ mutexFiltersConfig =} - const {= entitiesToShowRenderVar =} = this.props.{= entityLowerName =}List - {=/ mutexFiltersConfig =} - - return ( -
- - {=# mutexFiltersConfig =} - Filter:  - - {=/ mutexFiltersConfig =} - - - - - - {=# listFields =} - {= name =} - {=/ listFields =} - - - - - {{= entitiesToShowRenderVar =}.map(({= entityLowerName =}) => ( - - {=# listFields =} - {=# boolean =} - - this.props.update{= entityName =}( - {= entityLowerName =}.id, { '{= name =}': e.target.checked } - )} - /> - - {=/ boolean =} - {=# string =} - this.finishEditing({= entityLowerName =}) }> - this.setAsBeingEdited({= entityLowerName =})} - > - {this.props.editable && this.isBeingEdited({= entityLowerName =}) ? ( - this.props.update{= entityName =}( - {= entityLowerName =}.id, { '{= name =}': e.target.value } - )} - /> - ) : ( - {=# render =} - this.{= renderFnName =}({= entityLowerName =}) - {=/ render =} - {=^ render =} - {= entityLowerName =}.{= name =} - {=/ render =} - )} - - - {=/ string =} - {=/ listFields =} - - ))} - -
-
-
- ) - } -} - -export default connect(state => ({ - // Selectors - {= entityLowerName =}List: {= entityLowerName =}State.selectors.all(state) -}), { - // Actions - update{= entityName =}: {= entityLowerName =}Actions.update -})({= listName =}) diff --git a/waspc/data/Generator/templates/react-app/src/entities/_entity/state.js b/waspc/data/Generator/templates/react-app/src/entities/_entity/state.js deleted file mode 100644 index ccab55547..000000000 --- a/waspc/data/Generator/templates/react-app/src/entities/_entity/state.js +++ /dev/null @@ -1,66 +0,0 @@ -{{={= =}=}} -import { createSelector } from 'reselect' - -import {=entityClassName=} from './{=entityClassName=}' -import * as types from './actionTypes' - - -// We assume that root reducer of the app will put this reducer under -// key ROOT_REDUCER_KEY. -const ROOT_REDUCER_KEY = 'entities/{=entity.name=}' - -const initialState = { - all: [] -} - -const reducer = (state = initialState, action) => { - switch (action.type) { - case types.ADD: - return { - ...state, - all: [ ...state.all, action.data ] - } - - case types.SET: - return { - ...state, - all: action.{=_entities=} - } - - case types.UPDATE: - return { - ...state, - all: state.all.map( - {=_entity=} => - {=_entity=}.id === action.id - ? { ...{=_entity=}, ...action.data } - : {=_entity=} - ) - } - - case types.REMOVE: - return { - ...state, - all: state.all.filter( - {=_entity=} => {=_entity=}.id !== action.id - ) - } - - default: - return state - } -} - - -let selectors = {} -selectors.root = (state) => state[ROOT_REDUCER_KEY] - -/** - * @returns {{= entity.name =}[]} - */ -selectors.all = createSelector(selectors.root, (state) => { - return state.all.map(data => new {=entityClassName=}(data)) -}) - - -export { reducer, initialState, selectors, ROOT_REDUCER_KEY } diff --git a/waspc/data/Generator/templates/react-app/src/index.js b/waspc/data/Generator/templates/react-app/src/index.js index d2722f72c..9c6afda1d 100644 --- a/waspc/data/Generator/templates/react-app/src/index.js +++ b/waspc/data/Generator/templates/react-app/src/index.js @@ -1,25 +1,18 @@ {{={= =}=}} import React from 'react' import ReactDOM from 'react-dom' -import { Provider } from 'react-redux' import { ReactQueryCacheProvider } from 'react-query' import router from './router' -import { configureStore } from './store' import queryCache from './queryCache' -import { rootReducer } from './reducers' import * as serviceWorker from './serviceWorker' import './index.css' -const store = configureStore(rootReducer) - ReactDOM.render( - - { router } - + { router } , document.getElementById('root') ) diff --git a/waspc/data/Generator/templates/react-app/src/reducers.js b/waspc/data/Generator/templates/react-app/src/reducers.js deleted file mode 100644 index 6cb2c57a4..000000000 --- a/waspc/data/Generator/templates/react-app/src/reducers.js +++ /dev/null @@ -1,23 +0,0 @@ -{{={= =}=}} -import { combineReducers } from 'redux' - -{=# entities =} -import * as {= entityLowerName =}State from '{= entityStatePath =}' -{=/ entities =} - - -const states = [ - {=# entities =} - {= entityLowerName =}State, - {=/ entities =} -] - -const keyToReducer = states.reduce((acc, state) => { - // We set the reducers here by using their ROOT_REDUCER_KEY, because their - // internal state implementations assume so. - return { ...acc, [state.ROOT_REDUCER_KEY]: state.reducer } -}, {}) - -export const rootReducer = combineReducers({ - ...keyToReducer -}) diff --git a/waspc/data/Generator/templates/react-app/src/store/index.js b/waspc/data/Generator/templates/react-app/src/store/index.js deleted file mode 100644 index d0c1f775b..000000000 --- a/waspc/data/Generator/templates/react-app/src/store/index.js +++ /dev/null @@ -1,27 +0,0 @@ -{{={= =}=}} -import * as RTK from '@reduxjs/toolkit' - -import loggerMiddleware from './middleware/logger' - -/** - * @param {Function} reducer - Redux reducer to be used for this store. - * @param {Object} [preloadedState] - State that this store will be initialized with. - * @returns {Object} Redux store, configured to suit our needs. - */ -export const configureStore = (reducer, preloadedState) => { - const middleware = [ - ...RTK.getDefaultMiddleware(), - loggerMiddleware - ] - - const enhancers = [] - - const store = RTK.configureStore({ - reducer, - preloadedState, - middleware, - enhancers - }) - - return store -} diff --git a/waspc/data/Generator/templates/react-app/src/store/middleware/logger.js b/waspc/data/Generator/templates/react-app/src/store/middleware/logger.js deleted file mode 100644 index 4538c16ca..000000000 --- a/waspc/data/Generator/templates/react-app/src/store/middleware/logger.js +++ /dev/null @@ -1,14 +0,0 @@ -{{={= =}=}} -const logger = store => next => action => { - console.group(action.type) - console.info('dispatching', action) - - let result = next(action) - - console.log('next state', store.getState()) - console.groupEnd() - - return result -} - -export default logger diff --git a/waspc/src/Generator/WebAppGenerator.hs b/waspc/src/Generator/WebAppGenerator.hs index f2fcbb088..e09e293d1 100644 --- a/waspc/src/Generator/WebAppGenerator.hs +++ b/waspc/src/Generator/WebAppGenerator.hs @@ -10,7 +10,9 @@ import qualified Path as P import CompileOptions (CompileOptions) import Generator.ExternalCodeGenerator (generateExternalCodeDir) import Generator.FileDraft -import Generator.PackageJsonGenerator (resolveNpmDeps, toPackageJsonDependenciesString) +import Generator.PackageJsonGenerator (resolveNpmDeps, + toPackageJsonDependenciesString) +import qualified Generator.WebAppGenerator.AuthG as AuthG import Generator.WebAppGenerator.Common (asTmplFile, asWebAppFile, asWebAppSrcFile) @@ -18,12 +20,9 @@ import qualified Generator.WebAppGenerator.Common as C import qualified Generator.WebAppGenerator.ExternalCodeGenerator as WebAppExternalCodeGenerator import Generator.WebAppGenerator.OperationsGenerator (genOperations) import qualified Generator.WebAppGenerator.RouterGenerator as RouterGenerator -import qualified Generator.WebAppGenerator.AuthG as AuthG import qualified NpmDependency as ND import StrongPath (Dir, Path, Rel, ()) -import qualified StrongPath as SP -import qualified Util import Wasp import qualified Wasp.NpmDependencies as WND @@ -60,17 +59,13 @@ genPackageJson wasp waspDeps = C.makeTemplateFD waspNpmDeps :: [ND.NpmDependency] waspNpmDeps = ND.fromList - [ ("@material-ui/core", "^4.9.1") - , ("@reduxjs/toolkit", "^1.2.3") - , ("axios", "^0.20.0") + [ ("axios", "^0.20.0") , ("lodash", "^4.17.15") , ("react", "^16.12.0") , ("react-dom", "^16.12.0") , ("react-query", "^2.14.1") - , ("react-redux", "^7.1.3") , ("react-router-dom", "^5.1.2") , ("react-scripts", "3.4.0") - , ("redux", "^4.0.5") , ("uuid", "^3.4.0") ] @@ -102,12 +97,9 @@ generateSrcDir wasp [ [P.relfile|index.js|] , [P.relfile|index.css|] , [P.relfile|serviceWorker.js|] - , [P.relfile|store/index.js|] - , [P.relfile|store/middleware/logger.js|] , [P.relfile|config.js|] , [P.relfile|queryCache.js|] ] - ++ [generateReducersJs wasp] ++ genOperations wasp ++ AuthG.genAuth wasp where @@ -117,13 +109,3 @@ generateSrcDir wasp makeSimpleSrcTemplateFD path = C.makeTemplateFD (asTmplFile $ [P.reldir|src|] P. path) (srcDir asWebAppSrcFile path) (Just $ toJSON wasp) - --- TODO: Remove this -generateReducersJs :: Wasp -> FileDraft -generateReducersJs wasp = C.makeTemplateFD tmplPath dstPath (Just templateData) - where - tmplPath = asTmplFile [P.relfile|src/reducers.js|] - dstPath = srcDir asWebAppSrcFile [P.relfile|reducers.js|] - templateData = object - [ "wasp" .= wasp - ] diff --git a/waspc/test/Generator/WebAppGeneratorTest.hs b/waspc/test/Generator/WebAppGeneratorTest.hs index d874fee16..fa84ae200 100644 --- a/waspc/test/Generator/WebAppGeneratorTest.hs +++ b/waspc/test/Generator/WebAppGeneratorTest.hs @@ -6,7 +6,6 @@ import System.FilePath (()) import qualified Path as P import qualified StrongPath as SP -import Util import qualified CompileOptions import Generator.WebAppGenerator import Generator.FileDraft @@ -48,11 +47,8 @@ spec_WebAppGenerator = do [ "logo.png" , "index.css" , "index.js" - , "reducers.js" , "router.js" , "serviceWorker.js" - , "store" "index.js" - , "store" "middleware" "logger.js" ] ]