diff --git a/client/coral-admin/src/AppRouter.js b/client/coral-admin/src/AppRouter.js index bfb2e197c..af3423acc 100644 --- a/client/coral-admin/src/AppRouter.js +++ b/client/coral-admin/src/AppRouter.js @@ -42,6 +42,9 @@ const routes = ( + + + diff --git a/client/coral-admin/src/components/ActionButton.js b/client/coral-admin/src/components/ActionButton.js index 1fcafeac0..ae75b829e 100644 --- a/client/coral-admin/src/components/ActionButton.js +++ b/client/coral-admin/src/components/ActionButton.js @@ -6,6 +6,13 @@ import {menuActionsMap} from '../containers/ModerationQueue/helpers/moderationQu const ActionButton = ({type = '', status, ...props}) => { const typeName = type.toLowerCase(); const active = ((type === 'REJECT' && status === 'REJECTED') || (type === 'APPROVE' && status === 'ACCEPTED')); + let text = menuActionsMap[type].text; + + if (text === 'Approve' && active) { + text = 'Approved'; + } else if (text === 'Reject' && active) { + text = 'Rejected'; + } return ( + >{text} ); }; diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js index dffa4de26..eb59f369e 100644 --- a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js +++ b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js @@ -138,6 +138,9 @@ class ModerationContainer extends Component { case 'all': activeTabCount = data.allCount; break; + case 'accepted': + activeTabCount = data.acceptedCount; + break; case 'premod': activeTabCount = data.premodCount; break; @@ -155,6 +158,7 @@ class ModerationContainer extends Component { { function getPath (type) { @@ -28,6 +28,12 @@ const ModerationMenu = ( activeClassName={styles.active}> {lang.t('modqueue.all')} + + {lang.t('modqueue.approved')} + { + const comment = oldData.all.find(c => c.id === commentId); + comment.status = 'ACCEPTED'; const premod = oldData.premod.filter(c => c.id !== commentId); const flagged = oldData.flagged.filter(c => c.id !== commentId); + const accepted = [comment].concat(oldData.accepted); const rejected = oldData.rejected.filter(c => c.id !== commentId); const premodCount = premod.length < oldData.premod.length ? oldData.premodCount - 1 : oldData.premodCount; const flaggedCount = flagged.length < oldData.flagged.length ? oldData.flaggedCount - 1 : oldData.flaggedCount; const rejectedCount = rejected.length < oldData.rejected.length ? oldData.rejectedCount - 1 : oldData.rejectedCount; + const acceptedCount = oldData.acceptedCount + 1; return { ...oldData, premodCount, flaggedCount, + acceptedCount, rejectedCount, premod, flagged, + accepted, rejected, }; } @@ -82,21 +88,26 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, { }, updateQueries: { ModQueue: (oldData) => { - const comment = oldData.premod.concat(oldData.flagged).filter(c => c.id === commentId)[0]; + const comment = oldData.all.find(c => c.id === commentId); + comment.status = 'REJECTED'; const rejected = [comment].concat(oldData.rejected); const premod = oldData.premod.filter(c => c.id !== commentId); const flagged = oldData.flagged.filter(c => c.id !== commentId); + const accepted = oldData.accepted.filter(c => c.id !== commentId); const premodCount = premod.length < oldData.premod.length ? oldData.premodCount - 1 : oldData.premodCount; const flaggedCount = flagged.length < oldData.flagged.length ? oldData.flaggedCount - 1 : oldData.flaggedCount; const rejectedCount = oldData.rejectedCount + 1; + const acceptedCount = accepted.length < oldData.accepted.length ? oldData.acceptedCount - 1 : oldData.acceptedCount; return { ...oldData, premodCount, flaggedCount, + acceptedCount, rejectedCount, premod, flagged, + accepted, rejected }; } diff --git a/client/coral-admin/src/graphql/queries/modQueueQuery.graphql b/client/coral-admin/src/graphql/queries/modQueueQuery.graphql index f124b87b5..80dec5ff7 100644 --- a/client/coral-admin/src/graphql/queries/modQueueQuery.graphql +++ b/client/coral-admin/src/graphql/queries/modQueueQuery.graphql @@ -8,6 +8,13 @@ query ModQueue ($asset_id: ID, $sort: SORT_ORDER) { }) { ...commentView } + accepted: comments(query: { + statuses: [ACCEPTED], + asset_id: $asset_id, + sort: $sort + }) { + ...commentView + } premod: comments(query: { statuses: [PREMOD], asset_id: $asset_id, @@ -38,6 +45,10 @@ query ModQueue ($asset_id: ID, $sort: SORT_ORDER) { allCount: commentCount(query: { asset_id: $asset_id }) + acceptedCount: commentCount(query: { + statuses: [ACCEPTED], + asset_id: $asset_id + }) premodCount: commentCount(query: { statuses: [PREMOD], asset_id: $asset_id diff --git a/client/coral-admin/src/translations.json b/client/coral-admin/src/translations.json index b6ac46b01..6401f4990 100644 --- a/client/coral-admin/src/translations.json +++ b/client/coral-admin/src/translations.json @@ -36,6 +36,7 @@ "modqueue": { "likes": "likes", "all": "all", + "approved": "approved", "premod": "pre-mod", "rejected": "rejected", "flagged": "flagged", @@ -227,6 +228,8 @@ "loading": "Cargando resultados" }, "modqueue": { + "all": "todos", + "approved": "aprobado", "likes": "gustos", "premod": "pre-mod", "rejected": "rechazado", diff --git a/client/coral-embed-stream/src/components/Embed.js b/client/coral-embed-stream/src/components/Embed.js index db1bcfa1d..0d26cf740 100644 --- a/client/coral-embed-stream/src/components/Embed.js +++ b/client/coral-embed-stream/src/components/Embed.js @@ -33,12 +33,14 @@ export default class Embed extends React.Component { } } + handleShowProfile = () => this.props.setActiveTab('profile'); + render () { const {activeTab, logout, viewAllComments, commentId} = this.props; const {asset: {totalCommentCount}} = this.props.root; const {loggedIn, isAdmin, user} = this.props.auth; - const userBox = ; + const userBox = ; return (
diff --git a/client/coral-embed-stream/src/containers/Embed.js b/client/coral-embed-stream/src/containers/Embed.js index 12e05eed8..d5399fc60 100644 --- a/client/coral-embed-stream/src/containers/Embed.js +++ b/client/coral-embed-stream/src/containers/Embed.js @@ -3,6 +3,8 @@ import {compose, gql, graphql} from 'react-apollo'; import {connect} from 'react-redux'; import {bindActionCreators} from 'redux'; import isEqual from 'lodash/isEqual'; +import branch from 'recompose/branch'; +import renderComponent from 'recompose/renderComponent'; import {Spinner} from 'coral-ui'; import {authActions, assetActions, pym} from 'coral-framework'; @@ -19,7 +21,6 @@ class EmbedContainer extends React.Component { componentDidMount() { pym.sendMessage('childReady'); - this.props.checkLogin(); } componentWillReceiveProps(nextProps) { @@ -108,6 +109,10 @@ const mapDispatchToProps = dispatch => export default compose( connect(mapStateToProps, mapDispatchToProps), + branch( + props => !props.auth.checkedInitialLogin, + renderComponent(Spinner), + ), withQuery, )(EmbedContainer); diff --git a/client/coral-embed-stream/src/containers/Stream.js b/client/coral-embed-stream/src/containers/Stream.js index 4df7fc960..4415f5f94 100644 --- a/client/coral-embed-stream/src/containers/Stream.js +++ b/client/coral-embed-stream/src/containers/Stream.js @@ -118,7 +118,9 @@ class StreamContainer extends React.Component { }; componentDidMount() { - this.props.data.refetch(); + if (this.props.previousTab) { + this.props.data.refetch(); + } this.countPoll = setInterval(() => { const {asset} = this.props.root; this.getCounts({ @@ -236,6 +238,7 @@ const mapStateToProps = state => ({ assetId: state.stream.assetId, assetUrl: state.stream.assetUrl, activeTab: state.embed.activeTab, + previousTab: state.embed.previousTab, }); const mapDispatchToProps = dispatch => diff --git a/client/coral-embed-stream/src/index.js b/client/coral-embed-stream/src/index.js index f3f6075b6..2fd1e2731 100644 --- a/client/coral-embed-stream/src/index.js +++ b/client/coral-embed-stream/src/index.js @@ -3,6 +3,7 @@ import {render} from 'react-dom'; import {ApolloProvider} from 'react-apollo'; import {client} from 'coral-framework/services/client'; +import {checkLogin} from 'coral-framework/actions/auth'; import reducers from './reducers'; import localStore, {injectReducers} from 'coral-framework/services/store'; @@ -12,6 +13,11 @@ injectReducers(reducers); const store = (window.opener && window.opener.coralStore) ? window.opener.coralStore : localStore; +// Don't run this in the popup. +if (store === localStore) { + store.dispatch(checkLogin()); +} + render( diff --git a/client/coral-embed-stream/src/reducers/embed.js b/client/coral-embed-stream/src/reducers/embed.js index e7fe5a533..0fd661543 100644 --- a/client/coral-embed-stream/src/reducers/embed.js +++ b/client/coral-embed-stream/src/reducers/embed.js @@ -2,6 +2,7 @@ import * as actions from '../constants/embed'; const initialState = { activeTab: 'stream', + previousTab: '', }; export default function stream(state = initialState, action) { @@ -10,6 +11,7 @@ export default function stream(state = initialState, action) { return { ...state, activeTab: action.tab, + previousTab: state.activeTab, }; default: return state; diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js index 6e678cab9..83ea49ce5 100644 --- a/client/coral-framework/reducers/auth.js +++ b/client/coral-framework/reducers/auth.js @@ -8,6 +8,7 @@ const initialState = Map({ user: null, showSignInDialog: false, showCreateUsernameDialog: false, + checkedInitialLogin: false, view: 'SIGNIN', error: '', passwordRequestSuccess: null, @@ -71,10 +72,12 @@ export default function auth (state = initialState, action) { .set('isLoading', true); case actions.CHECK_LOGIN_FAILURE: return state + .set('checkedInitialLogin', true) .set('loggedIn', false) .set('user', null); case actions.CHECK_LOGIN_SUCCESS: return state + .set('checkedInitialLogin', true) .set('loggedIn', true) .set('isAdmin', action.isAdmin) .set('user', purge(action.user)); @@ -114,7 +117,11 @@ export default function auth (state = initialState, action) { .set('isLoading', false) .set('successSignUp', true); case actions.LOGOUT_SUCCESS: - return initialState; + return state + .set('user', null) + .set('isLoading', false) + .set('loggedIn', false) + .set('isAdmin', false); case actions.INVALID_FORM: return state .set('error', action.error); diff --git a/client/coral-sign-in/components/UserBox.js b/client/coral-sign-in/components/UserBox.js index 8e718614b..a44c3d4fb 100644 --- a/client/coral-sign-in/components/UserBox.js +++ b/client/coral-sign-in/components/UserBox.js @@ -4,11 +4,11 @@ import I18n from 'coral-framework/modules/i18n/i18n'; import translations from '../translations'; const lang = new I18n(translations); -const UserBox = ({className, user, logout, changeTab}) => ( +const UserBox = ({className, user, onLogout, onShowProfile}) => (
{lang.t('signIn.loggedInAs')} - changeTab(1)}>{user.username}. {lang.t('signIn.notYou')} - {lang.t('signIn.logout')} + {user.username}. {lang.t('signIn.notYou')} + {lang.t('signIn.logout')}
); diff --git a/package.json b/package.json index 26e64fbbb..250c0549f 100644 --- a/package.json +++ b/package.json @@ -96,11 +96,15 @@ "prop-types": "^15.5.8", "react-apollo": "^1.1.0", "react-recaptcha": "^2.2.6", + "recompose": "^0.23.1", "redis": "^2.7.1", "uuid": "^3.0.1", "simplemde": "^1.11.2", + "subscriptions-transport-ws": "^0.5.5-alpha.0", "resolve": "^1.3.2", - "semver": "^5.3.0" + "semver": "^5.3.0", + "simplemde": "^1.11.2", + "uuid": "^3.0.1" }, "devDependencies": { "apollo-client": "^1.0.4", @@ -179,8 +183,8 @@ "redux-thunk": "^2.1.0", "regenerator": "^0.8.46", "selenium-standalone": "^5.11.2", - "subscriptions-transport-ws": "^0.5.5-alpha.0", "style-loader": "^0.16.0", + "subscriptions-transport-ws": "^0.5.5-alpha.0", "supertest": "^2.0.1", "timeago.js": "^2.0.3", "webpack": "^2.3.1" diff --git a/yarn.lock b/yarn.lock index 1584ce2d1..81a4c7a41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,10 @@ git-url-parse "^6.0.2" shelljs "^0.7.0" +"@types/async@^2.0.31": + version "2.0.40" + resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.40.tgz#ac02de68e66c004a61b7cb16df8b1db3a254cca9" + "@types/express-serve-static-core@*": version "4.0.44" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.0.44.tgz#a1c3bd5d80e93c72fba91a03f5412c47f21d4ae7" @@ -26,6 +30,14 @@ version "0.8.6" resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.8.6.tgz#b34fb880493ba835b0c067024ee70130d6f9bb68" +"@types/graphql@^0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@types/graphql/-/graphql-0.9.0.tgz#fccf859f0d2817687f210737dc3be48a18b1d754" + +"@types/isomorphic-fetch@0.0.33": + version "0.0.33" + resolved "https://registry.yarnpkg.com/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.33.tgz#3ea1b86f8b73e6a7430d01d4dbd5b1f63fd72718" + "@types/mime@*": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-0.0.29.tgz#fbcfd330573b912ef59eeee14602bface630754b" @@ -1474,6 +1486,10 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +change-emitter@^0.1.2: + version "0.1.6" + resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" + character-parser@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" @@ -2982,7 +2998,7 @@ fastparse@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" -fbjs@^0.8.4, fbjs@^0.8.9: +fbjs@^0.8.1, fbjs@^0.8.4, fbjs@^0.8.9: version "0.8.12" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04" dependencies: @@ -3503,7 +3519,7 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" -graphql-anywhere@^3.0.0: +graphql-anywhere@^3.0.0, graphql-anywhere@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/graphql-anywhere/-/graphql-anywhere-3.0.1.tgz#73531db861174c8f212eafb9f8e84944b38b4e5a" @@ -3586,7 +3602,7 @@ graphql@^0.7.2: dependencies: iterall "1.0.2" -graphql@^0.9.1: +graphql@^0.9.1, graphql@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.9.3.tgz#71fc0fa331bffb9c20678485861cfb370803118e" dependencies: @@ -3727,7 +3743,7 @@ hoek@4.x.x: version "4.1.1" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.1.1.tgz#9cc573ffba2b7b408fb5e9c2a13796be94cddce9" -hoist-non-react-statics@^1.0.3, hoist-non-react-statics@^1.2.0: +hoist-non-react-statics@^1.0.0, hoist-non-react-statics@^1.0.3, hoist-non-react-statics@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" @@ -4953,11 +4969,11 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@3.10.1: +lodash@3.10.1, lodash@^3.3.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@3.9.3, lodash@^3.3.1: +lodash@3.9.3: version "3.9.3" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.9.3.tgz#0159e86832feffc6d61d852b12a953b99496bd32" @@ -6847,7 +6863,19 @@ readable-stream@1.1, readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@2, readable-stream@2.2.7, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.2.6: +readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.2.6: + version "2.2.9" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8" + dependencies: + buffer-shims "~1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~1.0.0" + util-deprecate "~1.0.1" + +readable-stream@2.2.7: version "2.2.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1" dependencies: @@ -6919,6 +6947,15 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +recompose@^0.23.1: + version "0.23.1" + resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.23.1.tgz#577613e24a7ff56f9ca6b899190f8a9c0857fc20" + dependencies: + change-emitter "^0.1.2" + fbjs "^0.8.1" + hoist-non-react-statics "^1.0.0" + symbol-observable "^1.0.4" + redis-commands@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.3.1.tgz#81d826f45fa9c8b2011f4cd7a0fe597d241d442b" @@ -6976,7 +7013,7 @@ redux-thunk@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5" -redux@^3.6.0: +redux@^3.4.0, redux@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/redux/-/redux-3.6.0.tgz#887c2b3d0b9bd86eca2be70571c27654c19e188d" dependencies: @@ -7766,7 +7803,7 @@ svgo@^0.7.0: version "0.0.21" resolved "https://registry.yarnpkg.com/sylvester/-/sylvester-0.0.21.tgz#2987b1ce2bd2f38b0dce2a34388884bfa4400ea7" -symbol-observable@^1.0.2: +symbol-observable@^1.0.2, symbol-observable@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" @@ -8254,7 +8291,7 @@ whatwg-encoding@^1.0.1: dependencies: iconv-lite "0.4.13" -whatwg-fetch@>=0.10.0: +whatwg-fetch@>=0.10.0, whatwg-fetch@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" @@ -8324,7 +8361,7 @@ word-wrap@1.2.1, word-wrap@^1.0.3: version "1.2.1" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.1.tgz#248f459b465d179a17bc407c854d3151d07e45d8" -wordwrap@0.0.2: +wordwrap@0.0.2, wordwrap@~0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -8332,10 +8369,6 @@ wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"