Port 65506bac3f
to glitch-soc
Signed-off-by: Thibaut Girka <thib@sitedethib.com>
master
parent
50f5254568
commit
511edccf61
@ -0,0 +1,69 @@ |
||||
import api from 'flavours/glitch/util/api'; |
||||
|
||||
export const ACCOUNT_NOTE_SUBMIT_REQUEST = 'ACCOUNT_NOTE_SUBMIT_REQUEST'; |
||||
export const ACCOUNT_NOTE_SUBMIT_SUCCESS = 'ACCOUNT_NOTE_SUBMIT_SUCCESS'; |
||||
export const ACCOUNT_NOTE_SUBMIT_FAIL = 'ACCOUNT_NOTE_SUBMIT_FAIL'; |
||||
|
||||
export const ACCOUNT_NOTE_INIT_EDIT = 'ACCOUNT_NOTE_INIT_EDIT'; |
||||
export const ACCOUNT_NOTE_CANCEL = 'ACCOUNT_NOTE_CANCEL'; |
||||
|
||||
export const ACCOUNT_NOTE_CHANGE_COMMENT = 'ACCOUNT_NOTE_CHANGE_COMMENT'; |
||||
|
||||
export function submitAccountNote() { |
||||
return (dispatch, getState) => { |
||||
dispatch(submitAccountNoteRequest()); |
||||
|
||||
const id = getState().getIn(['account_notes', 'edit', 'account_id']); |
||||
|
||||
api(getState).post(`/api/v1/accounts/${id}/note`, { |
||||
comment: getState().getIn(['account_notes', 'edit', 'comment']), |
||||
}).then(response => { |
||||
dispatch(submitAccountNoteSuccess(response.data)); |
||||
}).catch(error => dispatch(submitAccountNoteFail(error))); |
||||
}; |
||||
}; |
||||
|
||||
export function submitAccountNoteRequest() { |
||||
return { |
||||
type: ACCOUNT_NOTE_SUBMIT_REQUEST, |
||||
}; |
||||
}; |
||||
|
||||
export function submitAccountNoteSuccess(relationship) { |
||||
return { |
||||
type: ACCOUNT_NOTE_SUBMIT_SUCCESS, |
||||
relationship, |
||||
}; |
||||
}; |
||||
|
||||
export function submitAccountNoteFail(error) { |
||||
return { |
||||
type: ACCOUNT_NOTE_SUBMIT_FAIL, |
||||
error, |
||||
}; |
||||
}; |
||||
|
||||
export function initEditAccountNote(account) { |
||||
return (dispatch, getState) => { |
||||
const comment = getState().getIn(['relationships', account.get('id'), 'note']); |
||||
|
||||
dispatch({ |
||||
type: ACCOUNT_NOTE_INIT_EDIT, |
||||
account, |
||||
comment, |
||||
}); |
||||
}; |
||||
}; |
||||
|
||||
export function cancelAccountNote() { |
||||
return { |
||||
type: ACCOUNT_NOTE_CANCEL, |
||||
}; |
||||
}; |
||||
|
||||
export function changeAccountNoteComment(comment) { |
||||
return { |
||||
type: ACCOUNT_NOTE_CHANGE_COMMENT, |
||||
comment, |
||||
}; |
||||
}; |
@ -0,0 +1,103 @@ |
||||
import React from 'react'; |
||||
import ImmutablePropTypes from 'react-immutable-proptypes'; |
||||
import PropTypes from 'prop-types'; |
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; |
||||
import ImmutablePureComponent from 'react-immutable-pure-component'; |
||||
import Icon from 'flavours/glitch/components/icon'; |
||||
import Textarea from 'react-textarea-autosize'; |
||||
|
||||
const messages = defineMessages({ |
||||
placeholder: { id: 'account_note.placeholder', defaultMessage: 'No comment provided' }, |
||||
}); |
||||
|
||||
export default @injectIntl |
||||
class Header extends ImmutablePureComponent { |
||||
|
||||
static propTypes = { |
||||
account: ImmutablePropTypes.map.isRequired, |
||||
isEditing: PropTypes.bool, |
||||
isSubmitting: PropTypes.bool, |
||||
accountNote: PropTypes.string, |
||||
onEditAccountNote: PropTypes.func.isRequired, |
||||
onCancelAccountNote: PropTypes.func.isRequired, |
||||
onSaveAccountNote: PropTypes.func.isRequired, |
||||
onChangeAccountNote: PropTypes.func.isRequired, |
||||
intl: PropTypes.object.isRequired, |
||||
}; |
||||
|
||||
handleChangeAccountNote = (e) => { |
||||
this.props.onChangeAccountNote(e.target.value); |
||||
}; |
||||
|
||||
componentWillUnmount () { |
||||
if (this.props.isEditing) { |
||||
this.props.onCancelAccountNote(); |
||||
} |
||||
} |
||||
|
||||
handleKeyDown = e => { |
||||
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) { |
||||
this.props.onSaveAccountNote(); |
||||
} else if (e.keyCode === 27) { |
||||
this.props.onCancelAccountNote(); |
||||
} |
||||
} |
||||
|
||||
render () { |
||||
const { account, accountNote, isEditing, isSubmitting, intl } = this.props; |
||||
|
||||
if (!account || (!accountNote && !isEditing)) { |
||||
return null; |
||||
} |
||||
|
||||
let action_buttons = null; |
||||
if (isEditing) { |
||||
action_buttons = ( |
||||
<div className='account__header__account-note__buttons'> |
||||
<button className='text-btn' tabIndex='0' onClick={this.props.onCancelAccountNote} disabled={isSubmitting}> |
||||
<Icon id='times' size={15} /> <FormattedMessage id='account_note.cancel' defaultMessage='Cancel' /> |
||||
</button> |
||||
<div className='flex-spacer' /> |
||||
<button className='text-btn' tabIndex='0' onClick={this.props.onSaveAccountNote} disabled={isSubmitting}> |
||||
<Icon id='check' size={15} /> <FormattedMessage id='account_note.save' defaultMessage='Save' /> |
||||
</button> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
let note_container = null; |
||||
if (isEditing) { |
||||
note_container = ( |
||||
<Textarea |
||||
className='account__header__account-note__content' |
||||
disabled={isSubmitting} |
||||
placeholder={intl.formatMessage(messages.placeholder)} |
||||
value={accountNote} |
||||
onChange={this.handleChangeAccountNote} |
||||
onKeyDown={this.handleKeyDown} |
||||
autoFocus |
||||
/> |
||||
); |
||||
} else { |
||||
note_container = (<div className='account__header__account-note__content'>{accountNote}</div>); |
||||
} |
||||
|
||||
return ( |
||||
<div className='account__header__account-note'> |
||||
<div className='account__header__account-note__header'> |
||||
<strong><FormattedMessage id='account.account_note_header' defaultMessage='Your note for @{name}' values={{ name: account.get('username') }} /></strong> |
||||
{!isEditing && ( |
||||
<div> |
||||
<button className='text-btn' tabIndex='0' onClick={this.props.onEditAccountNote} disabled={isSubmitting}> |
||||
<Icon id='pencil' size={15} /> <FormattedMessage id='account_note.edit' defaultMessage='Edit' /> |
||||
</button> |
||||
</div> |
||||
)} |
||||
</div> |
||||
{note_container} |
||||
{action_buttons} |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,34 @@ |
||||
import { connect } from 'react-redux'; |
||||
import { changeAccountNoteComment, submitAccountNote, initEditAccountNote, cancelAccountNote } from 'flavours/glitch/actions/account_notes'; |
||||
import AccountNote from '../components/account_note'; |
||||
|
||||
const mapStateToProps = (state, { account }) => { |
||||
const isEditing = state.getIn(['account_notes', 'edit', 'account_id']) === account.get('id'); |
||||
|
||||
return { |
||||
isSubmitting: state.getIn(['account_notes', 'edit', 'isSubmitting']), |
||||
accountNote: isEditing ? state.getIn(['account_notes', 'edit', 'comment']) : account.getIn(['relationship', 'note']), |
||||
isEditing, |
||||
}; |
||||
}; |
||||
|
||||
const mapDispatchToProps = (dispatch, { account }) => ({ |
||||
|
||||
onEditAccountNote() { |
||||
dispatch(initEditAccountNote(account)); |
||||
}, |
||||
|
||||
onSaveAccountNote() { |
||||
dispatch(submitAccountNote()); |
||||
}, |
||||
|
||||
onCancelAccountNote() { |
||||
dispatch(cancelAccountNote()); |
||||
}, |
||||
|
||||
onChangeAccountNote(comment) { |
||||
dispatch(changeAccountNoteComment(comment)); |
||||
}, |
||||
}); |
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AccountNote); |
@ -0,0 +1,44 @@ |
||||
import { Map as ImmutableMap } from 'immutable'; |
||||
|
||||
import { |
||||
ACCOUNT_NOTE_INIT_EDIT, |
||||
ACCOUNT_NOTE_CANCEL, |
||||
ACCOUNT_NOTE_CHANGE_COMMENT, |
||||
ACCOUNT_NOTE_SUBMIT_REQUEST, |
||||
ACCOUNT_NOTE_SUBMIT_FAIL, |
||||
ACCOUNT_NOTE_SUBMIT_SUCCESS, |
||||
} from '../actions/account_notes'; |
||||
|
||||
const initialState = ImmutableMap({ |
||||
edit: ImmutableMap({ |
||||
isSubmitting: false, |
||||
account_id: null, |
||||
comment: null, |
||||
}), |
||||
}); |
||||
|
||||
export default function account_notes(state = initialState, action) { |
||||
switch (action.type) { |
||||
case ACCOUNT_NOTE_INIT_EDIT: |
||||
return state.withMutations((state) => { |
||||
state.setIn(['edit', 'isSubmitting'], false); |
||||
state.setIn(['edit', 'account_id'], action.account.get('id')); |
||||
state.setIn(['edit', 'comment'], action.comment); |
||||
}); |
||||
case ACCOUNT_NOTE_CHANGE_COMMENT: |
||||
return state.setIn(['edit', 'comment'], action.comment); |
||||
case ACCOUNT_NOTE_SUBMIT_REQUEST: |
||||
return state.setIn(['edit', 'isSubmitting'], true); |
||||
case ACCOUNT_NOTE_SUBMIT_FAIL: |
||||
return state.setIn(['edit', 'isSubmitting'], false); |
||||
case ACCOUNT_NOTE_SUBMIT_SUCCESS: |
||||
case ACCOUNT_NOTE_CANCEL: |
||||
return state.withMutations((state) => { |
||||
state.setIn(['edit', 'isSubmitting'], false); |
||||
state.setIn(['edit', 'account_id'], null); |
||||
state.setIn(['edit', 'comment'], null); |
||||
}); |
||||
default: |
||||
return state; |
||||
} |
||||
} |
Loading…
Reference in new issue