From 7a1fa663af05b7d302bb7da70a13b01830fbeae5 Mon Sep 17 00:00:00 2001 From: Andrew Nicolaou Date: Mon, 16 Sep 2019 22:58:32 +0200 Subject: [PATCH] Edit sketch name/description --- client/constants.js | 1 + client/modules/IDE/actions/collections.js | 22 +++++++ client/modules/IDE/reducers/collections.js | 5 +- client/modules/User/components/Collection.jsx | 58 +++++++++++++++++-- client/styles/components/_collection.scss | 20 +++++++ 5 files changed, 99 insertions(+), 7 deletions(-) diff --git a/client/constants.js b/client/constants.js index 76a3bfe5..7657c930 100644 --- a/client/constants.js +++ b/client/constants.js @@ -41,6 +41,7 @@ export const CREATE_COLLECTION = 'CREATED_COLLECTION'; export const ADD_TO_COLLECTION = 'ADD_TO_COLLECTION'; export const REMOVE_FROM_COLLECTION = 'REMOVE_FROM_COLLECTION'; +export const EDIT_COLLECTION = 'EDIT_COLLECTION'; export const DELETE_PROJECT = 'DELETE_PROJECT'; diff --git a/client/modules/IDE/actions/collections.js b/client/modules/IDE/actions/collections.js index df05f2f7..27266468 100644 --- a/client/modules/IDE/actions/collections.js +++ b/client/modules/IDE/actions/collections.js @@ -126,3 +126,25 @@ export function removeFromCollection(collectionId, projectId) { }); }; } + +export function editCollection(collectionId, { name, description }) { + return (dispatch) => { + const url = `${ROOT_URL}/collections/${collectionId}`; + return axios.patch(url, { name, description }, { withCredentials: true }) + .then((response) => { + dispatch({ + type: ActionTypes.EDIT_COLLECTION, + payload: response.data + }); + return response.data; + }) + .catch((response) => { + dispatch({ + type: ActionTypes.ERROR, + error: response.data + }); + + return response.data; + }); + }; +} diff --git a/client/modules/IDE/reducers/collections.js b/client/modules/IDE/reducers/collections.js index 4c4027b1..b8e8622b 100644 --- a/client/modules/IDE/reducers/collections.js +++ b/client/modules/IDE/reducers/collections.js @@ -5,8 +5,9 @@ const sketches = (state = [], action) => { case ActionTypes.SET_COLLECTIONS: return action.collections; - // The API returns the complete new collection - // with the items added or removed + // The API returns the complete new edited collection + // with any items added or removed + case ActionTypes.EDIT_COLLECTION: case ActionTypes.ADD_TO_COLLECTION: case ActionTypes.REMOVE_FROM_COLLECTION: return state.map((collection) => { diff --git a/client/modules/User/components/Collection.jsx b/client/modules/User/components/Collection.jsx index 0a467d96..c910d39d 100644 --- a/client/modules/User/components/Collection.jsx +++ b/client/modules/User/components/Collection.jsx @@ -15,6 +15,7 @@ import * as SortingActions from '../../IDE/actions/sorting'; import * as IdeActions from '../../IDE/actions/ide'; import { getCollection } from '../../IDE/selectors/collections'; import Loader from '../../App/components/loader'; +import EditableInput from '../../IDE/components/EditableInput'; const arrowUp = require('../../../images/sort-arrow-up.svg'); const arrowDown = require('../../../images/sort-arrow-down.svg'); @@ -240,10 +241,24 @@ class Collection extends React.Component { return `p5.js Web Editor | ${this.props.username}'s collections`; } + getUsername() { + return this.props.username !== undefined ? this.props.username : this.props.user.username; + } + getCollectionName() { return this.props.collection.name; } + isOwner() { + let isOwner = false; + + if (this.props.user != null && this.props.user.username && this.props.collection.owner.username === this.props.user.username) { + isOwner = true; + } + + return isOwner; + } + hasCollection() { return !this.props.loading && this.props.collection != null; } @@ -258,13 +273,47 @@ class Collection extends React.Component { } _renderCollectionMetadata() { - const { name, description, items, owner } = this.props.collection; + const { + id, name, description, items, owner + } = this.props.collection; + + const handleEditCollectionName = (value) => { + if (value === name) { + return; + } + + this.props.editCollection(id, { name: value }); + }; + + const handleEditCollectionDescription = (value) => { + if (value === description) { + return; + } + + this.props.editCollection(id, { description: value }); + }; return (
-

{name}

+

+ { + this.isOwner() ? : name + } +

+

{items.length} sketches collected by {owner.username}

-

{description}

+ +

+ { + this.isOwner() ? + : + description + } +

); } @@ -298,7 +347,6 @@ class Collection extends React.Component { } render() { - const username = this.props.username !== undefined ? this.props.username : this.props.user.username; const title = this.hasCollection() ? this.getCollectionName() : null; return ( @@ -326,7 +374,7 @@ class Collection extends React.Component { key={item.id} item={item} user={this.props.user} - username={username} + username={this.getUsername()} />))} } diff --git a/client/styles/components/_collection.scss b/client/styles/components/_collection.scss index f49c7345..dbec678c 100644 --- a/client/styles/components/_collection.scss +++ b/client/styles/components/_collection.scss @@ -12,10 +12,30 @@ } } +.collection-metadata__name { + padding: #{12 / $base-font-size}rem 0; +} + +.collection-metadata__name .editable-input__label span { + padding: 0.83333rem 0; +} + +.collection-metadata__name, +.collection-metadata__name .editable-input__input { + font-size: 1.75rem; + font-weight: bold; +} + .collection-metadata__user { padding-top: #{12 / $base-font-size}rem; + padding-left: #{8 / $base-font-size}rem; } .collection-metadata__description { padding-top: #{24 / $base-font-size}rem; + width: 50%; +} + +.collection-metadata__description .editable-input__input { + width: 100%; }