diff --git a/src/components/modal/addtostudio/modal.scss b/src/components/modal/addtostudio/modal.scss index 03640f753..9544e1e04 100644 --- a/src/components/modal/addtostudio/modal.scss +++ b/src/components/modal/addtostudio/modal.scss @@ -134,6 +134,14 @@ color: $type-gray; } +.studio-selector-button-enabled { + pointer-events: auto; +} + +.studio-selector-button-disabled { + pointer-events: none; +} + .studio-status-icon { position: absolute; right: .625rem; diff --git a/src/components/modal/addtostudio/presentation.jsx b/src/components/modal/addtostudio/presentation.jsx index 7152ef8cc..6754b8fb7 100644 --- a/src/components/modal/addtostudio/presentation.jsx +++ b/src/components/modal/addtostudio/presentation.jsx @@ -26,6 +26,8 @@ const AddToStudioModalPresentation = ({ const contentLabel = intl.formatMessage({id: 'addToStudio.title'}); const studioButtons = studios.map(studio => ( @@ -69,6 +74,8 @@ const StudioButton = ({ }; StudioButton.propTypes = { + canAdd: PropTypes.bool, + canRemove: PropTypes.bool, hasRequestOutstanding: PropTypes.bool, includesProject: PropTypes.bool, onClick: PropTypes.func, diff --git a/src/views/preview/add-to-studio.jsx b/src/views/preview/add-to-studio.jsx index 80d517231..cf14b6ea5 100644 --- a/src/views/preview/add-to-studio.jsx +++ b/src/views/preview/add-to-studio.jsx @@ -3,26 +3,59 @@ const connect = require('react-redux').connect; const previewActions = require('../../redux/preview.js'); const AddToStudioModal = require('../../components/modal/addtostudio/container.jsx'); +// user can add project to studio if studio is open to all, or user is a curator of studio +const canAdd = (studio, userIsCurator) => ( + studio.open_to_all || userIsCurator +); + +// user can remove project from studio if user owns project or is admin or user is a curator of studio +const canRemove = (userOwnsProject, isAdmin, userIsCurator) => ( + userOwnsProject || isAdmin || userIsCurator +); + +// include a given studio in the list to show in add to studio modal. +// only include it if user has the ability to remove the project from this studio. +const showStudio = (studio, currentStudioIds, userIsCurator, userOwnsProject, isAdmin) => { + const includesProject = (currentStudioIds.indexOf(studio.id) !== -1); + const canAddToThisStudio = canAdd(studio, userIsCurator); + const canRemoveFromThisStudio = canRemove(userOwnsProject, isAdmin, userIsCurator); + if (canRemoveFromThisStudio) { // power to remove matches set of studios we want to show + // include the current status of whether the project is in the studio, + // and what privileges the user has to change that. + const consolidatedStudio = Object.assign({}, studio, { + includesProject: includesProject, + canAdd: canAddToThisStudio, + canRemove: canRemoveFromThisStudio + }); + return consolidatedStudio; + } + return null; +}; + // Build consolidated curatedStudios object from all studio info. // We add flags to indicate whether the project is currently in the studio, // and the status of requests to join/leave studios. -const consolidateStudiosInfo = (curatedStudios, projectStudios, currentStudioIds, studioRequests) => { +const consolidateStudiosInfo = (userOwnsProject, isAdmin, curatedStudios, projectStudios, + currentStudioIds, studioRequests) => { + const consolidatedStudios = []; + // for each studio the project is in, include it if user can add or remove project from it. projectStudios.forEach(projectStudio => { - const includesProject = (currentStudioIds.indexOf(projectStudio.id) !== -1); - const consolidatedStudio = - Object.assign({}, projectStudio, {includesProject: includesProject}); - consolidatedStudios.push(consolidatedStudio); + const userIsCurator = curatedStudios.some(curatedStudio => (curatedStudio.id === projectStudio.id)); + const studioToShow = showStudio(projectStudio, currentStudioIds, userIsCurator, userOwnsProject, isAdmin); + if (studioToShow) { + consolidatedStudios.push(studioToShow); + } }); - // copy the curated studios that project is not in + // for each curated studio, if it was not already added to consolidatedStudios above, add it now. curatedStudios.forEach(curatedStudio => { if (!projectStudios.some(projectStudio => (projectStudio.id === curatedStudio.id))) { - const includesProject = (currentStudioIds.indexOf(curatedStudio.id) !== -1); - const consolidatedStudio = - Object.assign({}, curatedStudio, {includesProject: includesProject}); - consolidatedStudios.push(consolidatedStudio); + const studioToShow = showStudio(curatedStudio, currentStudioIds, true, userOwnsProject, isAdmin); + if (studioToShow) { + consolidatedStudios.push(studioToShow); + } } }); @@ -32,16 +65,16 @@ const consolidateStudiosInfo = (curatedStudios, projectStudios, currentStudioIds const id = consolidatedStudio.id; consolidatedStudio.hasRequestOutstanding = ((id in studioRequests) && - (studioRequests[id] === previewActions.Status.FETCHING)); + (studioRequests[id] === previewActions.Status.FETCHING)); }); return consolidatedStudios; }; -const mapStateToProps = state => ({ - studios: consolidateStudiosInfo(state.preview.curatedStudios, - state.preview.projectStudios, state.preview.currentStudioIds, - state.preview.status.studioRequests) +const mapStateToProps = (state, ownProps) => ({ + studios: consolidateStudiosInfo(ownProps.userOwnsProject, ownProps.isAdmin, + state.preview.curatedStudios, state.preview.projectStudios, + state.preview.currentStudioIds, state.preview.status.studioRequests) }); const mapDispatchToProps = () => ({}); diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx index c4bce61fc..abb041bac 100644 --- a/src/views/preview/presentation.jsx +++ b/src/views/preview/presentation.jsx @@ -67,6 +67,7 @@ const PreviewPresentation = ({ faved, favoriteCount, intl, + isAdmin, isFullScreen, isLoggedIn, isNewScratcher, @@ -122,6 +123,7 @@ const PreviewPresentation = ({ showAdminPanel, showModInfo, singleCommentId, + userOwnsProject, visibilityInfo }) => { const shareDate = ((projectInfo.history && projectInfo.history.shared)) ? projectInfo.history.shared : ''; @@ -344,9 +346,11 @@ const PreviewPresentation = ({ ( {props.addToStudioOpen && ( @@ -80,6 +82,7 @@ Subactions.propTypes = { addToStudioOpen: PropTypes.bool, canAddToStudio: PropTypes.bool, canReport: PropTypes.bool, + isAdmin: PropTypes.bool, onAddToStudioClicked: PropTypes.func, onAddToStudioClosed: PropTypes.func, onCopyProjectLink: PropTypes.func, @@ -88,7 +91,8 @@ Subactions.propTypes = { onReportSubmit: PropTypes.func.isRequired, onToggleStudio: PropTypes.func, reportOpen: PropTypes.bool, - shareDate: PropTypes.string + shareDate: PropTypes.string, + userOwnsProject: PropTypes.bool }; module.exports = Subactions;