mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-30 02:22:49 +00:00
update ui to include invitedAuthors array
This commit is contained in:
@@ -250,6 +250,8 @@ const MetadataEditor = createClass({
|
|||||||
|
|
||||||
render : function(){
|
render : function(){
|
||||||
return <div className='metadataEditor'>
|
return <div className='metadataEditor'>
|
||||||
|
<h1 className='sectionHead'>Brew</h1>
|
||||||
|
|
||||||
<div className='field title'>
|
<div className='field title'>
|
||||||
<label>title</label>
|
<label>title</label>
|
||||||
<input type='text' className='value'
|
<input type='text' className='value'
|
||||||
@@ -283,8 +285,6 @@ const MetadataEditor = createClass({
|
|||||||
values={this.props.metadata.tags}
|
values={this.props.metadata.tags}
|
||||||
onChange={(e)=>this.handleFieldChange('tags', e)}/>
|
onChange={(e)=>this.handleFieldChange('tags', e)}/>
|
||||||
|
|
||||||
{this.renderAuthors()}
|
|
||||||
|
|
||||||
<div className='field systems'>
|
<div className='field systems'>
|
||||||
<label>systems</label>
|
<label>systems</label>
|
||||||
<div className='value'>
|
<div className='value'>
|
||||||
@@ -296,6 +296,23 @@ const MetadataEditor = createClass({
|
|||||||
|
|
||||||
{this.renderRenderOptions()}
|
{this.renderRenderOptions()}
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<h1 className='sectionHead'>Authors</h1>
|
||||||
|
|
||||||
|
{this.renderAuthors()}
|
||||||
|
|
||||||
|
<StringArrayEditor label='invited authors' valuePatterns={[/.+/]}
|
||||||
|
validators={[(v)=>!this.props.metadata.authors.includes(v)]}
|
||||||
|
placeholder='invite author' unique={true}
|
||||||
|
values={this.props.metadata.invitedAuthors}
|
||||||
|
notes={['Invited authors are case sensitive.', 'After adding an invited author, send them the edit link. There, they can choose to accept or decline the invitation.']}
|
||||||
|
onChange={(e)=>this.handleFieldChange('invitedAuthors', e)}/>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<h1 className='sectionHead'>Privacy</h1>
|
||||||
|
|
||||||
<div className='field publish'>
|
<div className='field publish'>
|
||||||
<label>publish</label>
|
<label>publish</label>
|
||||||
<div className='value'>
|
<div className='value'>
|
||||||
|
|||||||
@@ -10,6 +10,15 @@
|
|||||||
height : calc(100vh - 54px); // 54px is the height of the navbar + snippet bar. probably a better way to dynamic get this.
|
height : calc(100vh - 54px); // 54px is the height of the navbar + snippet bar. probably a better way to dynamic get this.
|
||||||
overflow-y : auto;
|
overflow-y : auto;
|
||||||
|
|
||||||
|
.sectionHead {
|
||||||
|
font-weight: 1000;
|
||||||
|
margin: 20px 0;
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
@@ -30,6 +39,7 @@
|
|||||||
}
|
}
|
||||||
.field{
|
.field{
|
||||||
display : flex;
|
display : flex;
|
||||||
|
flex-wrap : wrap;
|
||||||
width : 100%;
|
width : 100%;
|
||||||
min-width : 200px;
|
min-width : 200px;
|
||||||
&>label{
|
&>label{
|
||||||
@@ -78,6 +88,11 @@
|
|||||||
font-size : 0.8em;
|
font-size : 0.8em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size : 0.6em;
|
||||||
|
font-style : italic;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -128,10 +143,6 @@
|
|||||||
button.unpublish{
|
button.unpublish{
|
||||||
.button(@silver);
|
.button(@silver);
|
||||||
}
|
}
|
||||||
small{
|
|
||||||
font-size : 0.6em;
|
|
||||||
font-style : italic;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.delete.field .value{
|
.delete.field .value{
|
||||||
@@ -196,6 +207,7 @@
|
|||||||
}
|
}
|
||||||
.field .list {
|
.field .list {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex: 1 0;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ const StringArrayEditor = createClass({
|
|||||||
label : '',
|
label : '',
|
||||||
values : [],
|
values : [],
|
||||||
valuePatterns : null,
|
valuePatterns : null,
|
||||||
|
validators : [],
|
||||||
placeholder : '',
|
placeholder : '',
|
||||||
|
notes : [],
|
||||||
unique : false,
|
unique : false,
|
||||||
cannotEdit : [],
|
cannotEdit : [],
|
||||||
onChange : ()=>{}
|
onChange : ()=>{}
|
||||||
@@ -83,7 +85,8 @@ const StringArrayEditor = createClass({
|
|||||||
}
|
}
|
||||||
const matchesPatterns = !this.props.valuePatterns || this.props.valuePatterns.some((pattern)=>!!(value || '').match(pattern));
|
const matchesPatterns = !this.props.valuePatterns || this.props.valuePatterns.some((pattern)=>!!(value || '').match(pattern));
|
||||||
const uniqueIfSet = !this.props.unique || !values.includes(value);
|
const uniqueIfSet = !this.props.unique || !values.includes(value);
|
||||||
return matchesPatterns && uniqueIfSet;
|
const passesValidators = !this.props.validators || this.props.validators.every((validator)=>validator(value));
|
||||||
|
return matchesPatterns && uniqueIfSet && passesValidators;
|
||||||
},
|
},
|
||||||
|
|
||||||
handleValueInputKeyDown : function(event, index) {
|
handleValueInputKeyDown : function(event, index) {
|
||||||
@@ -123,17 +126,21 @@ const StringArrayEditor = createClass({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
return <div className='field values'>
|
return <div className='field'>
|
||||||
<label>{this.props.label}</label>
|
<label>{this.props.label}</label>
|
||||||
<div className='list'>
|
<div style={{ flex: '1 0' }}>
|
||||||
{valueElements}
|
<div className='list'>
|
||||||
<div className='input-group'>
|
{valueElements}
|
||||||
<input type='text' className={`value ${this.valueIsValid(this.state.temporaryValue) ? '' : 'invalid'}`} placeholder={this.props.placeholder}
|
<div className='input-group'>
|
||||||
value={this.state.temporaryValue}
|
<input type='text' className={`value ${this.valueIsValid(this.state.temporaryValue) ? '' : 'invalid'}`} placeholder={this.props.placeholder}
|
||||||
onKeyDown={(e)=>this.handleValueInputKeyDown(e)}
|
value={this.state.temporaryValue}
|
||||||
onChange={(e)=>this.setState({ temporaryValue: e.target.value })}/>
|
onKeyDown={(e)=>this.handleValueInputKeyDown(e)}
|
||||||
{this.valueIsValid(this.state.temporaryValue) ? <div className='icon steel' onClick={(e)=>{ e.stopPropagation(); this.addValue(this.state.temporaryValue); }}><i className='fa fa-check fa-fw'/></div> : null}
|
onChange={(e)=>this.setState({ temporaryValue: e.target.value })}/>
|
||||||
|
{this.valueIsValid(this.state.temporaryValue) ? <div className='icon steel' onClick={(e)=>{ e.stopPropagation(); this.addValue(this.state.temporaryValue); }}><i className='fa fa-check fa-fw'/></div> : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{this.props.notes ? this.props.notes.map((n)=><p><small>{n}</small></p>) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -330,6 +330,17 @@ const EditPage = createClass({
|
|||||||
</Nav.item>;
|
</Nav.item>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.state.errors.response.error.status === 409) {
|
||||||
|
console.log(this.state.errors.response);
|
||||||
|
const message = this.state.errors.response.body?.message;
|
||||||
|
return <Nav.item className='save error' icon='fas fa-exclamation-triangle'>
|
||||||
|
Oops!
|
||||||
|
<div className='errorContainer'>
|
||||||
|
{message ? message : 'Conflict: please refresh to get latest changes'}
|
||||||
|
</div>
|
||||||
|
</Nav.item>;
|
||||||
|
}
|
||||||
|
|
||||||
return <Nav.item className='save error' icon='fas fa-exclamation-triangle'>
|
return <Nav.item className='save error' icon='fas fa-exclamation-triangle'>
|
||||||
Oops!
|
Oops!
|
||||||
<div className='errorContainer'>
|
<div className='errorContainer'>
|
||||||
|
|||||||
Reference in New Issue
Block a user