Commit 647575e4 authored by Paul Kaplan's avatar Paul Kaplan

Move permissions into its own reducer

parent 82da633e
const {selectUserId, selectIsAdmin, selectIsSocial, selectIsLoggedIn} = require('./session');
// Fine-grain selector helpers - not exported, use the higher level selectors below
const isCreator = state => selectUserId(state) === state.studio.owner;
const isCurator = state => state.studio.curator;
const isManager = state => state.studio.manager || isCreator(state);
// Action-based permissions selectors
const selectCanEditInfo = state => selectIsAdmin(state) || isManager(state);
const selectCanAddProjects = state =>
isManager(state) ||
isCurator(state) ||
(selectIsSocial(state) && state.studio.openToAll);
// This isn't "canComment" since they could be muted, but comment composer handles that
const selectShowCommentComposer = state => selectIsSocial(state);
const selectCanReportComment = state => selectIsSocial(state);
const selectCanRestoreComment = state => selectIsAdmin(state);
// On the project page, project owners can delete comments with a confirmation,
// and admins can delete comments without a confirmation. For now, only admins
// can delete studio comments, so the following two are the same.
const selectCanDeleteComment = state => selectIsAdmin(state);
const selectCanDeleteCommentWithoutConfirm = state => selectIsAdmin(state);
const selectCanFollowStudio = state => selectIsLoggedIn(state);
export {
selectCanEditInfo,
selectCanAddProjects,
selectCanFollowStudio,
selectShowCommentComposer,
selectCanDeleteComment,
selectCanDeleteCommentWithoutConfirm,
selectCanReportComment,
selectCanRestoreComment
};
...@@ -3,10 +3,7 @@ const keyMirror = require('keymirror'); ...@@ -3,10 +3,7 @@ const keyMirror = require('keymirror');
const api = require('../lib/api'); const api = require('../lib/api');
const log = require('../lib/log'); const log = require('../lib/log');
const { const {selectUsername, selectToken} = require('./session');
selectUserId, selectIsAdmin, selectIsSocial, selectUsername, selectToken,
selectIsLoggedIn
} = require('./session');
const Status = keyMirror({ const Status = keyMirror({
FETCHED: null, FETCHED: null,
...@@ -68,7 +65,6 @@ const studioReducer = (state, action) => { ...@@ -68,7 +65,6 @@ const studioReducer = (state, action) => {
}; };
// Action Creators // Action Creators
const setFetchStatus = (fetchType, fetchStatus, error) => ({ const setFetchStatus = (fetchType, fetchStatus, error) => ({
type: 'SET_FETCH_STATUS', type: 'SET_FETCH_STATUS',
fetchType, fetchType,
...@@ -86,36 +82,12 @@ const setRoles = roles => ({ ...@@ -86,36 +82,12 @@ const setRoles = roles => ({
roles: roles roles: roles
}); });
// Selectors
// Fine-grain selector helpers - not exported, use the higher level selectors below
const isCreator = state => selectUserId(state) === state.studio.owner;
const isCurator = state => state.studio.curator;
const isManager = state => state.studio.manager || isCreator(state);
// Action-based permissions selectors
const selectCanEditInfo = state => selectIsAdmin(state) || isManager(state);
const selectCanAddProjects = state =>
isManager(state) ||
isCurator(state) ||
(selectIsSocial(state) && state.studio.openToAll);
const selectShowCommentComposer = state => selectIsSocial(state);
const selectCanReportComment = state => selectIsSocial(state);
const selectCanRestoreComment = state => selectIsAdmin(state);
// On the project page, project owners can delete comments with a confirmation,
// and admins can delete comments without a confirmation. For now, only admins
// can delete studio comments, so the following two are the same.
const selectCanDeleteComment = state => selectIsAdmin(state);
const selectCanDeleteCommentWithoutConfirm = state => selectIsAdmin(state);
// Data selectors // Data selectors
const selectStudioId = state => state.studio.id; const selectStudioId = state => state.studio.id;
const selectStudioTitle = state => state.studio.title; const selectStudioTitle = state => state.studio.title;
const selectStudioDescription = state => state.studio.description; const selectStudioDescription = state => state.studio.description;
const selectIsLoadingInfo = state => state.studio.infoStatus === Status.FETCHING; const selectIsLoadingInfo = state => state.studio.infoStatus === Status.FETCHING;
const selectIsFollowing = state => state.studio.following; const selectIsFollowing = state => state.studio.following;
const selectCanFollowStudio = state => selectIsLoggedIn(state);
const selectIsLoadingRoles = state => state.studio.rolesStatus === Status.FETCHING; const selectIsLoadingRoles = state => state.studio.rolesStatus === Status.FETCHING;
// Thunks // Thunks
...@@ -180,13 +152,5 @@ module.exports = { ...@@ -180,13 +152,5 @@ module.exports = {
selectStudioDescription, selectStudioDescription,
selectIsLoadingInfo, selectIsLoadingInfo,
selectIsLoadingRoles, selectIsLoadingRoles,
selectIsFollowing, selectIsFollowing
selectCanEditInfo,
selectCanAddProjects,
selectShowCommentComposer,
selectCanDeleteComment,
selectCanDeleteCommentWithoutConfirm,
selectCanReportComment,
selectCanRestoreComment,
selectCanFollowStudio
}; };
...@@ -14,7 +14,7 @@ import { ...@@ -14,7 +14,7 @@ import {
selectCanDeleteCommentWithoutConfirm, selectCanDeleteCommentWithoutConfirm,
selectCanReportComment, selectCanReportComment,
selectCanRestoreComment selectCanRestoreComment
} from '../../redux/studio.js'; } from '../../redux/studio-permissions';
const StudioComments = ({ const StudioComments = ({
comments, comments,
......
...@@ -3,7 +3,8 @@ import React from 'react'; ...@@ -3,7 +3,8 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import {selectStudioDescription, selectIsLoadingInfo, selectCanEditInfo} from '../../redux/studio'; import {selectStudioDescription, selectIsLoadingInfo} from '../../redux/studio';
import {selectCanEditInfo} from '../../redux/studio-permissions';
import { import {
mutateStudioDescription, selectIsMutatingDescription, selectDescriptionMutationError mutateStudioDescription, selectIsMutatingDescription, selectDescriptionMutationError
} from '../../redux/studio-mutations'; } from '../../redux/studio-mutations';
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import {selectIsFollowing, selectIsLoadingRoles} from '../../redux/studio';
import {selectIsFollowing, selectCanFollowStudio, selectIsLoadingRoles} from '../../redux/studio'; import {selectCanFollowStudio} from '../../redux/studio-permissions';
import { import {
mutateFollowingStudio, selectIsMutatingFollowing, selectFollowingMutationError mutateFollowingStudio, selectIsMutatingFollowing, selectFollowingMutationError
} from '../../redux/studio-mutations'; } from '../../redux/studio-mutations';
......
...@@ -36,10 +36,7 @@ const StudioInfo = ({ ...@@ -36,10 +36,7 @@ const StudioInfo = ({
StudioInfo.propTypes = { StudioInfo.propTypes = {
isLoggedIn: PropTypes.bool, isLoggedIn: PropTypes.bool,
studio: PropTypes.shape({ studio: PropTypes.shape({}), // TODO remove, just for <Debug />
title: PropTypes.string,
description: PropTypes.description
}),
onLoadInfo: PropTypes.func, onLoadInfo: PropTypes.func,
onLoadRoles: PropTypes.func onLoadRoles: PropTypes.func
}; };
......
...@@ -5,10 +5,10 @@ import {connect} from 'react-redux'; ...@@ -5,10 +5,10 @@ import {connect} from 'react-redux';
import {projectFetcher} from './lib/fetchers'; import {projectFetcher} from './lib/fetchers';
import {projects} from './lib/redux-modules'; import {projects} from './lib/redux-modules';
import {selectCanAddProjects} from '../../redux/studio-permissions';
import Debug from './debug.jsx'; import Debug from './debug.jsx';
const {actions, selector: projectsSelector} = projects; const {actions, selector: projectsSelector} = projects;
import {selectCanAddProjects} from '../../redux/studio';
const StudioProjects = ({ const StudioProjects = ({
canAddProjects, items, error, loading, moreToLoad, onLoadMore canAddProjects, items, error, loading, moreToLoad, onLoadMore
......
...@@ -3,7 +3,8 @@ import React from 'react'; ...@@ -3,7 +3,8 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import {selectStudioTitle, selectIsLoadingInfo, selectCanEditInfo} from '../../redux/studio'; import {selectStudioTitle, selectIsLoadingInfo} from '../../redux/studio';
import {selectCanEditInfo} from '../../redux/studio-permissions';
import {mutateStudioTitle, selectIsMutatingTitle, selectTitleMutationError} from '../../redux/studio-mutations'; import {mutateStudioTitle, selectIsMutatingTitle, selectTitleMutationError} from '../../redux/studio-mutations';
const StudioTitle = ({ const StudioTitle = ({
......
import { import {
getInitialState as getInitialStudioState,
selectCanEditInfo, selectCanEditInfo,
selectCanAddProjects, selectCanAddProjects,
selectShowCommentComposer, selectShowCommentComposer,
selectCanDeleteComment, selectCanDeleteComment,
selectCanDeleteCommentWithoutConfirm, selectCanDeleteCommentWithoutConfirm,
selectCanReportComment, selectCanReportComment,
selectCanRestoreComment selectCanRestoreComment,
} from '../../../src/redux/studio'; selectCanFollowStudio
} from '../../../src/redux/studio-permissions';
import {
getInitialState as getInitialSessionState
} from '../../../src/redux/session';
import {getInitialState as getInitialStudioState} from '../../../src/redux/studio';
import {getInitialState as getInitialSessionState} from '../../../src/redux/session';
import {sessions, studios} from '../../helpers/state-fixtures.json'; import {sessions, studios} from '../../helpers/state-fixtures.json';
let state; let state;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment