diff --git a/client/coral-admin/src/actions/assets.js b/client/coral-admin/src/actions/assets.js new file mode 100644 index 000000000..1e5f2716d --- /dev/null +++ b/client/coral-admin/src/actions/assets.js @@ -0,0 +1,13 @@ +import {FETCH_ASSETS, UPDATE_ASSET} from '../constants/assets'; + +/** + * Action disptacher related to assets + */ + +export const updateAsset = (id, property, value) => (dispatch) => { + dispatch({type: UPDATE_ASSET, id, property, value}); +}; + +export const fetchAssets = (skip, limit, search, sort) => (dispatch) => { + dispatch({type: FETCH_ASSETS, skip, limit, search, sort}); +}; diff --git a/client/coral-admin/src/constants/assets.js b/client/coral-admin/src/constants/assets.js index 59b76390f..b13534726 100644 --- a/client/coral-admin/src/constants/assets.js +++ b/client/coral-admin/src/constants/assets.js @@ -1 +1,4 @@ -export const ASSETS_FETCH = 'ASSETS_FETCH'; +export const FETCH_ASSETS = 'FETCH_ASSETS'; +export const FETCH_ASSETS_SUCCESS = 'FETCH_ASSETS_SUCCESS'; +export const FETCH_ASSETS_FAILED = 'FETCH_ASSETS_FAILED'; +export const UPDATE_ASSET = 'UPDATE_ASSET'; diff --git a/client/coral-admin/src/containers/Streams/Streams.css b/client/coral-admin/src/containers/Streams/Streams.css index 5ad875b35..c64de7974 100644 --- a/client/coral-admin/src/containers/Streams/Streams.css +++ b/client/coral-admin/src/containers/Streams/Streams.css @@ -54,6 +54,30 @@ display: block; } +.statusMenu { + border-radius: 3px; + width: 10em; + text-align: center; + float: right; + border: 1px solid #ccc; + color: #fff; + cursor: pointer; +} + +.statusMenuOpen { + padding: 10px; + background-color: #4caf50; +} + +.statusMenuIcon { + float: right; +} + +.statusMenuClosed { + padding: 10px; + background-color: #000; +} + .hidden { display: none; } diff --git a/client/coral-admin/src/containers/Streams/Streams.js b/client/coral-admin/src/containers/Streams/Streams.js index 7b1778012..078f7c98a 100644 --- a/client/coral-admin/src/containers/Streams/Streams.js +++ b/client/coral-admin/src/containers/Streams/Streams.js @@ -2,7 +2,7 @@ import React, {Component} from 'react'; import styles from './Streams.css'; import {connect} from 'react-redux'; import I18n from 'coral-framework/modules/i18n/i18n'; -import {ASSETS_FETCH} from '../../constants/assets'; +import {fetchAssets, updateAsset} from '../../actions/assets'; import translations from '../../translations.json'; import { RadioGroup, @@ -17,7 +17,8 @@ class Streams extends Component { state = { searchTerm: '', sortBy: 'newest', - statusFilter: 'all' + statusFilter: 'all', + statusMenus: {} } componentDidMount () { @@ -33,9 +34,40 @@ class Streams extends Component { return `${d.getMonth() + 1}/${d.getDate()}/${d.getFullYear()}`; } - renderStatus = (closedAt) => { - const status = closedAt && new Date(closedAt) < Date.now ? lang.t('streams.closed') : lang.t('streams.open'); - return
{status}
; + onStatusClick = (closeStream, id, statusMenuOpen) => () => { + if (statusMenuOpen) { + this.setState(prev => { + prev.statusMenus[id] = false; + return prev; + }); + this.props.updateAsset(id, 'closedAt', closeStream ? Date.now() : null); + } else { + this.setState(prev => { + prev.statusMenus[id] = true; + return prev; + }); + } + } + + renderStatus = (closedAt, id) => { + const closed = closedAt && new Date(closedAt) < Date.now; + const statusMenuOpen = this.state.statusMenus[id]; + return
+
+ {closed ? lang.t('streams.closed') : lang.t('streams.open')} + {!statusMenuOpen && } +
+ { + statusMenuOpen && +
+ {!closed ? lang.t('streams.closed') : lang.t('streams.open')} +
+ } +
; } render () { @@ -101,14 +133,11 @@ const mapStateToProps = ({assets}) => { }; const mapDispatchToProps = (dispatch) => { return { - fetchAssets: (skip, limit, search, sort) => { - dispatch({ - type: ASSETS_FETCH, - skip, - limit, - search, - sort - }); + fetchAssets: (...args) => { + dispatch(fetchAssets.apply(this, args)); + }, + updateAsset: (...args) => { + dispatch(updateAsset.apply(this, args)); } }; }; diff --git a/client/coral-admin/src/reducers/assets.js b/client/coral-admin/src/reducers/assets.js index bdd1bcaf9..a1ca4c831 100644 --- a/client/coral-admin/src/reducers/assets.js +++ b/client/coral-admin/src/reducers/assets.js @@ -1,4 +1,5 @@ import {Map, List, fromJS} from 'immutable'; +import {FETCH_ASSETS_SUCCESS} from '../constants/assets'; const initialState = Map({ byId: Map(), @@ -7,7 +8,7 @@ const initialState = Map({ export default (state = initialState, action) => { switch (action.type) { - case 'ASSETS_FETCH_SUCCESS': return replaceAssets(action, state); + case FETCH_ASSETS_SUCCESS: return replaceAssets(action, state); default: return state; } }; diff --git a/client/coral-admin/src/services/talk-adapter.js b/client/coral-admin/src/services/talk-adapter.js index 6dc4d5827..1b824c13e 100644 --- a/client/coral-admin/src/services/talk-adapter.js +++ b/client/coral-admin/src/services/talk-adapter.js @@ -22,7 +22,7 @@ export default store => next => action => { return createComment(store, action.name, action.body); case 'USER_BAN': return userStatusUpdate(store, action.status, action.userId, action.commentId); - case 'ASSETS_FETCH': + case 'FETCH_ASSETS': return fetchAssets(store, action); } }; @@ -97,9 +97,9 @@ const fetchAssets = (store, action) => { return coralApi(`/assets?skip=${skip}&limit=${limit}&search=${search}`) .then(({result, count}) => /* Post comments and users to redux store. Actions will be posted when they are needed. */ - store.dispatch({type: 'ASSETS_FETCH_SUCCESS', + store.dispatch({type: 'FETCH_ASSETS_SUCCESS', assets: result, count })) - .catch(error => store.dispatch({type: 'ASSETS_FETCH_FAILED', error})); + .catch(error => store.dispatch({type: 'FETCH_ASSETS_FAILED', error})); };