Add better type checking when connecting components
This commit is contained in:
parent
150a02b344
commit
f2e44f477c
@ -1,7 +1,7 @@
|
||||
// Maybe this won't be necessary after this is merged:
|
||||
// https://github.com/Microsoft/TypeScript/pull/29478
|
||||
|
||||
export interface IAction<T, ActionType extends string> {
|
||||
export interface IAction<T = any, ActionType extends string = string> {
|
||||
payload: Promise<T> | T,
|
||||
type: ActionType
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import {Redirect} from '../components/Redirect'
|
||||
|
||||
export interface ILoginFormProps {
|
||||
error?: string
|
||||
onSubmit: () => Promise<IUser>
|
||||
onSubmit: () => void
|
||||
onChange: (name: string, value: string) => void
|
||||
data: ICredentials
|
||||
user?: IUser
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {Connector} from '../redux/Connector'
|
||||
import {ICredentials} from '@rondo/common'
|
||||
import {INewUser} from '@rondo/common'
|
||||
import {ILoginState} from './LoginReducer'
|
||||
import {IStateSelector} from '../redux'
|
||||
import {LoginActions} from './LoginActions'
|
||||
@ -7,9 +7,11 @@ import {RegisterForm} from './RegisterForm'
|
||||
import {bindActionCreators} from 'redux'
|
||||
import {withForm} from './withForm'
|
||||
|
||||
const defaultCredentials: ICredentials = {
|
||||
const defaultCredentials: INewUser = {
|
||||
username: '',
|
||||
password: '',
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
}
|
||||
|
||||
export class RegisterConnector extends Connector<ILoginState> {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import React from 'react'
|
||||
import {IAction} from '../actions'
|
||||
|
||||
export interface IComponentProps<Data> {
|
||||
onSubmit: () => void
|
||||
@ -9,7 +10,7 @@ export interface IComponentProps<Data> {
|
||||
}
|
||||
|
||||
export interface IFormHOCProps<Data> {
|
||||
onSubmit: (props: Data) => Promise<void>
|
||||
onSubmit: (props: Data) => IAction<any, any>
|
||||
// TODO figure out what would happen if the underlying child component
|
||||
// would have the same required property as the HOC, like onSuccess?
|
||||
onSuccess?: () => void
|
||||
@ -33,7 +34,9 @@ export function withForm<Data, Props extends IComponentProps<Data>>(
|
||||
handleSubmit = async (e: React.FormEvent) => {
|
||||
const {clearOnSuccess, onSuccess} = this.props
|
||||
e.preventDefault()
|
||||
await this.props.onSubmit(this.state)
|
||||
const promise = this.props.onSubmit(this.state)
|
||||
console.log('aaaaaaaaa', promise)
|
||||
await promise
|
||||
if (clearOnSuccess) {
|
||||
this.setState(initialState)
|
||||
}
|
||||
|
||||
@ -35,9 +35,9 @@ export abstract class Connector<LocalState> {
|
||||
|
||||
protected wrap<
|
||||
State,
|
||||
StateProps,
|
||||
DispatchProps,
|
||||
Props
|
||||
Props,
|
||||
StateProps extends Partial<Props>,
|
||||
DispatchProps extends Partial<Props>,
|
||||
>(
|
||||
getLocalState: IStateSelector<State, LocalState>,
|
||||
mapStateToProps: (state: LocalState) => StateProps,
|
||||
|
||||
@ -1,25 +1,26 @@
|
||||
import React from 'react'
|
||||
import {IAction} from '../actions'
|
||||
import {ITeam, ReadonlyRecord} from '@rondo/common'
|
||||
|
||||
export interface ITeamListProps {
|
||||
teamsById: ReadonlyRecord<number, ITeam>,
|
||||
teamIds: ReadonlyArray<number>,
|
||||
onAddTeam: (params: {name: string}) => Promise<void>
|
||||
onRemoveTeam: (params: {id: number}) => Promise<void>
|
||||
onUpdateTeam: (params: {id: number, name: string}) => Promise<void>
|
||||
onAddTeam: (params: {name: string}) => IAction
|
||||
onRemoveTeam: (params: {id: number}) => IAction
|
||||
onUpdateTeam: (params: {id: number, name: string}) => IAction
|
||||
editTeamId: number
|
||||
}
|
||||
|
||||
export interface ITeamProps {
|
||||
team: ITeam
|
||||
editTeamId: number // TODO handle edits via react-router params
|
||||
onRemoveTeam: (params: {id: number}) => Promise<void>
|
||||
onUpdateTeam: (params: {id: number, name: string}) => Promise<void>
|
||||
onRemoveTeam: (params: {id: number}) => IAction
|
||||
onUpdateTeam: (params: {id: number, name: string}) => IAction
|
||||
}
|
||||
|
||||
export interface IAddTeamProps {
|
||||
onAddTeam: (params: {name: string}) => Promise<void>
|
||||
onUpdateTeam: (params: {id: number, name: string}) => Promise<void>
|
||||
onAddTeam: (params: {name: string}) => IAction
|
||||
onUpdateTeam: (params: {id: number, name: string}) => IAction
|
||||
team?: ITeam
|
||||
}
|
||||
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
import React from 'react'
|
||||
import {IAction} from '../actions'
|
||||
import {ITeam, IUser, IUserInTeam, ReadonlyRecord} from '@rondo/common'
|
||||
import {TeamList} from './TeamList'
|
||||
import {TeamUserList} from './TeamUserList'
|
||||
// import {Route} from 'react-router-dom'
|
||||
|
||||
export interface ITeamManagerProps {
|
||||
createTeam: (params: {name: string}) => Promise<void>
|
||||
updateTeam: (params: {id: number, name: string}) => Promise<void>
|
||||
removeTeam: (params: {id: number}) => Promise<void>
|
||||
createTeam: (params: {name: string}) => IAction
|
||||
updateTeam: (params: {id: number, name: string}) => IAction
|
||||
removeTeam: (params: {id: number}) => IAction
|
||||
|
||||
addUser: (params: {userId: number, teamId: number}) => Promise<void>
|
||||
removeUser: (params: {userId: number, teamId: number}) => Promise<void>
|
||||
fetchMyTeams: () => void
|
||||
fetchUsersInTeam: () => void
|
||||
findUserByEmail: (email: string) => Promise<IUser>
|
||||
addUser: (params: {userId: number, teamId: number, roleId: number}) => IAction
|
||||
removeUser: (params: {userId: number, teamId: number}) => IAction
|
||||
fetchMyTeams: () => IAction
|
||||
fetchUsersInTeam: (params: {teamId: number}) => IAction
|
||||
findUserByEmail: (email: string) => IAction<IUser | undefined>
|
||||
|
||||
teamsById: ReadonlyRecord<number, ITeam>
|
||||
teamIds: ReadonlyArray<number>
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
import React from 'react'
|
||||
import {IUser, IUserInTeam, ReadonlyRecord} from '@rondo/common'
|
||||
import {IAction} from '../actions'
|
||||
|
||||
const EMPTY_ARRAY: ReadonlyArray<string> = []
|
||||
|
||||
export interface ITeamUsersProps {
|
||||
// fetchMyTeams: () => void,
|
||||
fetchUsersInTeam: (teamId: number) => void
|
||||
findUserByEmail: (email: string) => Promise<IUser>
|
||||
fetchUsersInTeam: (params: {teamId: number}) => IAction
|
||||
findUserByEmail: (email: string) => IAction
|
||||
|
||||
onAddUser: (params: {userId: number, teamId: number}) => Promise<void>
|
||||
onRemoveUser: (params: {userId: number, teamId: number}) => Promise<void>
|
||||
onAddUser: (params: {userId: number, teamId: number, roleId: number})
|
||||
=> IAction<IUserInTeam>
|
||||
onRemoveUser: (params: {userId: number, teamId: number}) => IAction
|
||||
|
||||
teamId: number
|
||||
userKeysByTeamId: ReadonlyRecord<number, ReadonlyArray<string>>
|
||||
@ -22,8 +24,12 @@ export interface ITeamUserProps {
|
||||
}
|
||||
|
||||
export interface IAddUserProps {
|
||||
onAddUser: (params: {userId: number, teamId: number}) => Promise<void>
|
||||
onSearchUser: (email: string) => Promise<IUser>
|
||||
onAddUser: (params: {
|
||||
userId: number,
|
||||
teamId: number,
|
||||
roleId: number,
|
||||
}) => IAction<IUserInTeam>
|
||||
onSearchUser: (email: string) => IAction<IUser>
|
||||
teamId: number
|
||||
}
|
||||
|
||||
@ -70,7 +76,7 @@ export class AddUser extends React.PureComponent<IAddUserProps, IAddUserState> {
|
||||
event.preventDefault()
|
||||
const {teamId} = this.props
|
||||
const {email} = this.state
|
||||
const user = await this.props.onSearchUser(email)
|
||||
const user = await this.props.onSearchUser(email).payload
|
||||
if (!user) {
|
||||
// TODO handle this better via 404 status code
|
||||
return
|
||||
@ -78,6 +84,7 @@ export class AddUser extends React.PureComponent<IAddUserProps, IAddUserState> {
|
||||
await this.props.onAddUser({
|
||||
teamId,
|
||||
userId: user.id,
|
||||
roleId: 1,
|
||||
})
|
||||
|
||||
this.setState({email: '', user: undefined})
|
||||
@ -111,7 +118,7 @@ export class TeamUserList extends React.PureComponent<ITeamUsersProps> {
|
||||
}
|
||||
async fetchUsersInTeam(teamId: number) {
|
||||
if (teamId) {
|
||||
await this.props.fetchUsersInTeam(teamId)
|
||||
await this.props.fetchUsersInTeam({teamId})
|
||||
}
|
||||
}
|
||||
render() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user