Removed redundant old templates and code (redux).

This commit is contained in:
Martin Sosic 2020-10-21 17:38:52 +02:00 committed by Martin Šošić
parent cb217fde44
commit 3ab248b584
13 changed files with 5 additions and 575 deletions

View File

@ -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 =})

View File

@ -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
}
}

View File

@ -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'

View File

@ -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
})

View File

@ -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 (
<div className={this.props.className}>
<form noValidate onSubmit={this.handleSubmit} action="javascript:void(0);">
{=# formFields =}
{=# boolean =}
{=# show =}
<div>
<FormControlLabel
{=# label =}
label="{= label =}"
{=/ label =}
control={
<Switch
checked={this.getField('{= name =}')}
onChange={() => this.toggleField('{= name =}')}
value="{= name =}"
/>
}
/>
</div>
{=/ show =}
{=/ boolean =}
{=# string =}
{=# show =}
<div>
<TextField
{=# label =}
label="{= label =}"
{=/ label =}
{=# placeholder =}
placeholder="{= placeholder =}"
{=/ placeholder =}
value={this.getField('{= name =}')}
onChange={event => this.setField('{= name =}', event.target.value)}
margin="normal"
fullWidth
InputLabelProps={{
shrink: true
}}
/>
</div>
{=/ show =}
{=/ string =}
{=/ formFields =}
{=# showSubmitButton =}
<div>
<Button type="submit" variant="contained" color="primary">
{this.props.submitButtonLabel || 'Submit'}
</Button>
</div>
{=/ showSubmitButton =}
</form>
</div>
)
}
}

View File

@ -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 (
<div className={this.props.className}>
{=# mutexFiltersConfig =}
Filter:&nbsp;
<Select
value={this.state.filterName}
onChange={this.handleFilterChange}
>
<MenuItem value="{= noFilterLabel =}">{= noFilterLabel =}</MenuItem>
{=# filters =}
<MenuItem value="{= name =}">{= name =}</MenuItem>
{=/ filters =}
</Select>
{=/ mutexFiltersConfig =}
<Paper>
<Table>
<TableHead{=^ showHeader =} style={{display: 'none'}}{=/ showHeader =}>
<TableRow>
{=# listFields =}
<TableCell width="{= widthAsPercent =}%">{= name =}</TableCell>
{=/ listFields =}
</TableRow>
</TableHead>
<TableBody>
{{= entitiesToShowRenderVar =}.map(({= entityLowerName =}) => (
<TableRow key={{= entityLowerName =}.id}>
{=# listFields =}
{=# boolean =}
<TableCell>
<Checkbox
checked={{= entityLowerName =}.{= name =}}
color="default"
inputProps={{
'aria-label': 'checkbox'
}}
disabled={!this.props.editable}
onChange={e => this.props.update{= entityName =}(
{= entityLowerName =}.id, { '{= name =}': e.target.checked }
)}
/>
</TableCell>
{=/ boolean =}
{=# string =}
<ClickAwayListener
onClickAway={() => this.finishEditing({= entityLowerName =}) }>
<TableCell
onDoubleClick={() => this.setAsBeingEdited({= entityLowerName =})}
>
{this.props.editable && this.isBeingEdited({= entityLowerName =}) ? (
<TextField
value={{= entityLowerName =}.{= name =}}
onChange={e => this.props.update{= entityName =}(
{= entityLowerName =}.id, { '{= name =}': e.target.value }
)}
/>
) : (
{=# render =}
this.{= renderFnName =}({= entityLowerName =})
{=/ render =}
{=^ render =}
{= entityLowerName =}.{= name =}
{=/ render =}
)}
</TableCell>
</ClickAwayListener>
{=/ string =}
{=/ listFields =}
</TableRow>
))}
</TableBody>
</Table>
</Paper>
</div>
)
}
}
export default connect(state => ({
// Selectors
{= entityLowerName =}List: {= entityLowerName =}State.selectors.all(state)
}), {
// Actions
update{= entityName =}: {= entityLowerName =}Actions.update
})({= listName =})

View File

@ -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 }

View File

@ -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(
<ReactQueryCacheProvider queryCache={queryCache}>
<Provider store={store}>
{ router }
</Provider>
{ router }
</ReactQueryCacheProvider>,
document.getElementById('root')
)

View File

@ -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
})

View File

@ -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
}

View File

@ -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

View File

@ -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
]

View File

@ -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"
]
]