got addtostudio modal state changes to work, though not updating to server yet

This commit is contained in:
Ben Wheeler 2018-06-19 10:13:40 -04:00
parent bc0a5f64f7
commit 16190f1147
3 changed files with 152 additions and 24 deletions

View file

@ -1,3 +1,7 @@
// NOTE: next questions:
// * should i make these buttons actual select/checkbox elements?
// then i could just submit the form or something, right?
const bindAll = require('lodash.bindall'); const bindAll = require('lodash.bindall');
const truncate = require('lodash.truncate'); const truncate = require('lodash.truncate');
const PropTypes = require('prop-types'); const PropTypes = require('prop-types');
@ -22,6 +26,7 @@ class AddToStudioModal extends React.Component {
constructor (props) { constructor (props) {
super(props); super(props);
bindAll(this, [ // NOTE: will need to add and bind callback fn to handle addind and removing studios bindAll(this, [ // NOTE: will need to add and bind callback fn to handle addind and removing studios
'handleToggleAdded',
'handleRequestClose', 'handleRequestClose',
'handleSubmit' 'handleSubmit'
]); ]);
@ -47,16 +52,95 @@ class AddToStudioModal extends React.Component {
// maybe i should calculate delta here? if studio was // maybe i should calculate delta here? if studio was
// left elsewhere and that status was not changed here, // left elsewhere and that status was not changed here,
// prolly didn't want to be changed! // prolly didn't want to be changed!
this.state = { this.state = {
waiting: false waiting: false,
onOrDirty: {}
}; };
} }
componentDidMount() {
this.updateOnOrDirty(this.props.projectStudios, this.props.myStudios);
}
componentWillReceiveProps(nextProps) {
this.updateOnOrDirty(nextProps.projectStudios, nextProps.myStudios);
}
updateOnOrDirty(projectStudios, myStudios) {
// NOTE: in theory, myStudios could have dropped some studios in
// onOrDirty, so we should check all existing onOrDirty and drop
// them too; otherwise we might retain a dirty change for a studio
// we no longer have permission for. In theory.
let onOrDirty = this.state.onOrDirty;
projectStudios.forEach((studio) => {
onOrDirty[studio.id] = {added: true, dirty: false};
});
console.log(projectStudios);
console.log(myStudios);
console.log(onOrDirty);
this.setState({onOrDirty: Object.assign({}, onOrDirty)});
}
handleToggleAdded(studioId) {
let onOrDirty = this.state.onOrDirty;
if (studioId in onOrDirty) {
if (onOrDirty[studioId].added === true) {
if (onOrDirty[studioId].dirty === true) {
// let's untrack the status of this studio, so it's
// un-added, and un-dirty again
delete onOrDirty[studioId];
} else { // it started off added, so it's dirty now
onOrDirty[studioId].added = false;
onOrDirty[studioId].dirty = true;
}
} else {
if (onOrDirty[studioId].dirty === true) {
// it was previously set to unadded. so let's set it to
// added, and NOT dirty. This is how it started out
onOrDirty[studioId].added = true;
onOrDirty[studioId].dirty = false;
}
// should never be added == false AND dirty == false
}
} else { // was not in onOrDirty; add it as added!
onOrDirty[studioId] = {added: true, dirty: true};
}
this.setState({onOrDirty: Object.assign({}, onOrDirty)});
}
handleRequestClose () { handleRequestClose () {
// NOTE that we do NOT clear onOrDirty, so we don't lose
// user's work from a stray click outside the modal...
// but maybe this should be different?
this.baseModal.handleRequestClose(); this.baseModal.handleRequestClose();
} }
handleSubmit (formData) { handleSubmit (formData) {
// NOTE: ignoring formData for now...
this.setState({waiting: true}); this.setState({waiting: true});
this.props.onAddToStudio(formData, err => { const onOrDirty = this.state.onOrDirty;
const studiosToAdd = Object.keys(onOrDirty)
.reduce(function(accumulator, key) {
if (onOrDirty[key].dirty === true &&
onOrDirty[key].added === true) {
accumulator.push(key);
}
return accumulator;
}, []);
const studiosToDelete = Object.keys(onOrDirty)
.reduce(function(accumulator, key) {
if (onOrDirty[key].dirty === true &&
onOrDirty[key].added === false) {
accumulator.push(key);
}
return accumulator;
}, []);
// When this modal is opened, and isOpen becomes true,
// onOrDirty should start with a clean slate
// NOTE: this doesn't seem to be working
this.setState({onOrDirty: {}});
this.props.onAddToStudio(studiosToAdd, studiosToDelete, err => {
if (err) log.error(err); if (err) log.error(err);
this.setState({ this.setState({
waiting: false waiting: false
@ -72,19 +156,26 @@ class AddToStudioModal extends React.Component {
type, type,
...modalProps ...modalProps
} = this.props; } = this.props;
const onOrDirty = this.state.onOrDirty;
const contentLabel = intl.formatMessage({id: `addToStudio.${type}`}); const contentLabel = intl.formatMessage({id: `addToStudio.${type}`});
const projectStudioButtons = projectStudios.map((studio, index) => ( const studioButtons = myStudios.map((studio, index) => {
<div className="studio-selector-button" key={studio.id}> const isAdded = (studio.id in onOrDirty &&
onOrDirty[studio.id].added === true);
return (
<div className={"studio-selector-button" +
(isAdded ? " studio-selector-button-selected" : "")}
key={studio.id}
onClick={() => this.handleToggleAdded(studio.id)}
>
{truncate(studio.title, {'length': 20, 'separator': /[,:\.;]*\s+/})} {truncate(studio.title, {'length': 20, 'separator': /[,:\.;]*\s+/})}
<div className={".studio-status-icon" +
(isAdded ? " .studio-status-icon-selected" : "")}
>
{isAdded ? "✓" : "+"}
</div> </div>
));
const myStudioButtons = myStudios.map((studio, index) => (
<div className="studio-selector-button" key={studio.id}>
{truncate(studio.title, {'length': 20, 'separator': /[,:\.;]*\s+/})}
+
</div> </div>
)); );
});
return ( return (
<Modal <Modal
@ -105,8 +196,7 @@ class AddToStudioModal extends React.Component {
<div className="studio-list-outer-scrollbox"> <div className="studio-list-outer-scrollbox">
<div className="studio-list-inner-scrollbox"> <div className="studio-list-inner-scrollbox">
<div className="studio-list-container"> <div className="studio-list-container">
{[...projectStudioButtons, {studioButtons}
...myStudioButtons]}
</div> </div>
</div> </div>
</div> </div>

View file

@ -67,9 +67,11 @@
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
flex-flow: row wrap; flex-flow: row wrap;
min-height: 30rem; /* NOTE: remove this, this is just to force scrolling */
padding: 1rem 3rem; padding: 1rem 3rem;
} }
/* NOTE: force scrolling: add to above:
min-height: 30rem;
*/
.studio-selector-button { .studio-selector-button {
background-color: $ui-white; background-color: $ui-white;
@ -82,3 +84,25 @@
box-sizing: border-box; box-sizing: border-box;
width: 40%; width: 40%;
} }
.studio-selector-button-selected {
background-color: $ui-green;
color: $ui-white;
}
.studio-status-icon {
background-color: $ui-blue;
color: $type-gray;
font-weight: 800;
height: 1.5rem;
margin: 0.5rem 0.5rem;
padding: 0.5rem 0.5rem;
border-radius: 0.75rem;
box-sizing: border-box;
width: 1.5rem;
}
.studio-status-icon-selected {
background-color: $ui-green;
color: $ui-white;
}

View file

@ -43,6 +43,16 @@ class PreviewPresentation extends React.Component {
reportOpen: false reportOpen: false
}; };
this.mockedMyStudios = [ this.mockedMyStudios = [
{
id: 1702295,
description: "Real open studio",
history: {created: "2015-11-15T00:24:35.000Z",
modified: "2018-05-01T00:14:48.000Z"},
image: "https://cdn2.scratch.mit.edu/get_image/gallery/1702295_170x100.png",
owner: 10689298,
stats: {followers: 0},
title: "Real open studio"
},
{ {
id: 0, id: 0,
description: "Wow, studio A rocks", description: "Wow, studio A rocks",
@ -84,13 +94,17 @@ class PreviewPresentation extends React.Component {
handleAddToStudioClose () { handleAddToStudioClose () {
this.setState({addToStudioOpen: false}); this.setState({addToStudioOpen: false});
} }
handleAddToStudioSubmit (formData, callback) { handleAddToStudioSubmit (studiosToAdd, studiosToDelete, callback) {
const data = { console.log('studios to add: ');
...formData, console.log(studiosToAdd);
id: this.props.projectId, console.log('studios to delete: ');
username: this.props.user.username console.log(studiosToDelete);
}; // const data = {
console.log('submit addToStudio data', data); // eslint-disable-line no-console // ...formData,
// id: this.props.projectId,
// username: this.props.user.username
// };
//console.log('submit addToStudio data', data); // eslint-disable-line no-console
// TODO: pass error to modal via callback. // TODO: pass error to modal via callback.
callback(); callback();
this.setState({addToStudioOpen: false}); this.setState({addToStudioOpen: false});