packages/client: Style TeamManager, fix error on delete

This commit is contained in:
Jerko Steiner 2019-03-25 13:28:07 +08:00
parent 3f96a128a0
commit c83fa2d6d4
6 changed files with 46 additions and 20 deletions

View File

@ -16,7 +16,7 @@ export type TeamActionType =
'TEAM_UPDATE_PENDING',
'TEAM_UPDATE_RESOLVED',
'TEAM_UPDATE_REJECTED'>
| IAsyncAction<{},
| IAsyncAction<{id: number},
'TEAM_REMOVE_PENDING',
'TEAM_REMOVE_RESOLVED',
'TEAM_REMOVE_REJECTED'>

View File

@ -2,7 +2,7 @@ import React from 'react'
import {ITeam, ReadonlyRecord} from '@rondo/common'
import {Link} from 'react-router-dom'
import {TeamActions} from './TeamActions'
import {FaPlusSquare, FaSave, FaEdit, FaTimes} from 'react-icons/fa'
import {FaPlusSquare, FaCheck, FaEdit, FaTimes} from 'react-icons/fa'
import {
Button, Control, Heading, Input, Panel, PanelHeading, PanelBlock
@ -65,10 +65,14 @@ export class TeamAdd extends React.PureComponent<IAddTeamProps, IAddTeamState> {
} else {
await onAddTeam({name})
}
this.setState({name: ''})
}
render() {
return (
<form className='team-add' onSubmit={this.handleSubmit}>
<form
autoComplete='off'
className='team-add'
onSubmit={this.handleSubmit}>
<Heading>
{this.props.team ? 'Edit team' : 'Add team'}
</Heading>
@ -80,15 +84,16 @@ export class TeamAdd extends React.PureComponent<IAddTeamProps, IAddTeamState> {
onChange={this.handleChange}
/>
<span className='icon is-left'>
<FaPlusSquare />
{this.props.team ? <FaEdit /> : <FaPlusSquare />}
</span>
</Control>
<div className='text-right mt-1'>
<Button
className='button is-primary'
isColor='dark'
className='button'
type='submit'
>
<FaSave className='mr-1' /> Save
<FaCheck className='mr-1' /> Save
</Button>
</div>
</form>

View File

@ -36,10 +36,8 @@ export class TeamManager extends React.PureComponent<ITeamManagerProps> {
await this.props.fetchMyTeams()
}
render() {
// TypeOrm changes BigInt fields to Strings because they can be tool
// large...
const editTeamId = this.props.match.params.teamId as any as
number | undefined
const {teamId} = this.props.match.params
const editTeamId = teamId ? Number(teamId) : undefined
return (
<div className='team-manager'>

View File

@ -1,4 +1,6 @@
import {ITeam, IUserInTeam, ReadonlyRecord, indexBy} from '@rondo/common'
import {
ITeam, IUserInTeam, ReadonlyRecord, indexBy, without,
} from '@rondo/common'
import {TeamActionType} from './TeamActions'
import {GetAction} from '../actions'
@ -70,7 +72,6 @@ export function Team(state = defaultState, action: TeamActionType): ITeamState {
[action.payload.id]: action.payload,
},
}
return state
case 'TEAM_USER_ADD_RESOLVED':
return {
...state,
@ -107,6 +108,12 @@ export function Team(state = defaultState, action: TeamActionType): ITeamState {
...usersByKey,
},
}
case 'TEAM_REMOVE_RESOLVED':
return {
...state,
teamIds: state.teamIds.filter(id => id !== action.payload.id),
teamsById: without(state.teamsById, action.payload.id),
}
case 'TEAM_CREATE_REJECTED':
case 'TEAM_UPDATE_REJECTED':
case 'TEAM_USER_ADD_REJECTED':

View File

@ -1,10 +1,10 @@
import React from 'react'
import {IUser, IUserInTeam, ReadonlyRecord} from '@rondo/common'
import {TeamActions} from './TeamActions'
import {FaUser, FaSave, FaTimes} from 'react-icons/fa'
import {FaUser, FaCheck, FaTimes} from 'react-icons/fa'
import {
Button, Control, Heading, Input, Panel, PanelHeading, PanelBlock
Button, Control, Heading, Help, Input, Panel, PanelHeading, PanelBlock
} from 'bloomer'
const EMPTY_ARRAY: ReadonlyArray<string> = []
@ -34,6 +34,7 @@ export interface IAddUserProps {
}
export interface IAddUserState {
error: string
email: string
user?: IUser
}
@ -55,6 +56,7 @@ export class TeamUser extends React.PureComponent<ITeamUserProps> {
<Button
aria-label='Remove'
isColor='danger'
isInverted
className='team-user-remove'
onClick={this.handleRemoveUser}
>
@ -70,6 +72,7 @@ export class AddUser extends React.PureComponent<IAddUserProps, IAddUserState> {
constructor(props: IAddUserProps) {
super(props)
this.state = {
error: '',
email: '',
user: undefined,
}
@ -85,6 +88,7 @@ export class AddUser extends React.PureComponent<IAddUserProps, IAddUserState> {
const user = await this.props.onSearchUser(email).payload
if (!user) {
// TODO handle this better via 404 status code
this.setState({error: 'No user found'})
return
}
await this.props.onAddUser({
@ -93,16 +97,17 @@ export class AddUser extends React.PureComponent<IAddUserProps, IAddUserState> {
roleId: 1,
})
this.setState({email: '', user: undefined})
// TODO handle failures
this.setState({error: '', email: '', user: undefined})
}
render() {
const {error} = this.state
return (
<form onSubmit={this.handleAddUser}>
<form autoComplete='off' onSubmit={this.handleAddUser}>
<Heading>Add User</Heading>
<Control hasIcons='left'>
<Input
isColor={error ? 'danger' : ''}
onChange={this.handleChangeEmail}
placeholder='Email'
type='email'
@ -111,13 +116,16 @@ export class AddUser extends React.PureComponent<IAddUserProps, IAddUserState> {
<span className='icon is-left'>
<FaUser />
</span>
{error && (
<Help isColor='danger'>{error}</Help>
)}
</Control>
<div className='mt-1 text-right'>
<Button
isColor='primary'
isColor='dark'
type='submit'
>
<FaSave className='mr-1' />
<FaCheck className='mr-1' />
Add
</Button>
</div>

View File

@ -4,11 +4,19 @@ import {IUserInTeam} from '@rondo/common'
import {IUserTeamParams} from './IUserTeamParams'
import {Team} from '../entities/Team'
import {UserTeam} from '../entities/UserTeam'
import {Validator, trim} from '../validator'
export class TeamService extends BaseService implements ITeamService {
// TODO check team limit per user
async create({name, userId}: {name: string, userId: number}) {
name = trim(name)
new Validator({name, userId})
.ensure('name')
.ensure('userId')
.throw()
const team = await this.getRepository(Team).save({
name,
userId,