0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2025-12-30 04:32:38 +00:00

update ui to include invitedAuthors array

This commit is contained in:
Charlie Humphreys
2022-12-13 21:06:47 -06:00
parent 354d01e980
commit e5febc1fef
4 changed files with 63 additions and 16 deletions

View File

@@ -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'>

View File

@@ -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;
> * { > * {

View File

@@ -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>;
} }

View File

@@ -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'>