0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-03 17:02:40 +00:00

Merge branch 'master' into pr/2745

This commit is contained in:
Trevor Buckner
2023-03-22 14:11:19 -04:00
30 changed files with 16121 additions and 29247 deletions

View File

@@ -6,6 +6,7 @@ const _ = require('lodash');
const cx = require('classnames');
const request = require('../../utils/request-middleware.js');
const Nav = require('naturalcrit/nav/nav.jsx');
const Combobox = require('client/components/combobox.jsx');
const StringArrayEditor = require('../stringArrayEditor/stringArrayEditor.jsx');
const Themes = require('themes/themes.json');
@@ -35,7 +36,8 @@ const MetadataEditor = createClass({
authors : [],
systems : [],
renderer : 'legacy',
theme : '5ePHB'
theme : '5ePHB',
lang : 'en'
},
onChange : ()=>{},
reportError : ()=>{}
@@ -76,6 +78,7 @@ const MetadataEditor = createClass({
const errMessage = validationErr.map((err)=>{
return `- ${err}`;
}).join('\n');
callIfExists(e.target, 'setCustomValidity', errMessage);
callIfExists(e.target, 'reportValidity');
}
@@ -111,6 +114,11 @@ const MetadataEditor = createClass({
this.props.onChange(this.props.metadata);
},
handleLanguage : function(languageCode){
this.props.metadata.lang = languageCode;
this.props.onChange(this.props.metadata);
},
handleDelete : function(){
if(this.props.metadata.authors && this.props.metadata.authors.length <= 1){
if(!confirm('Are you sure you want to delete this brew? Because you are the only owner of this brew, the document will be deleted permanently.')) return;
@@ -224,6 +232,47 @@ const MetadataEditor = createClass({
</div>;
},
renderLanguageDropdown : function(){
const langCodes = ['en', 'de', 'de-ch', 'fr', 'ja', 'es', 'it', 'sv', 'ru', 'zh-Hans', 'zh-Hant'];
const listLanguages = ()=>{
return _.map(langCodes.sort(), (code, index)=>{
const localName = new Intl.DisplayNames([code], { type: 'language' });
const englishName = new Intl.DisplayNames('en', { type: 'language' });
return <div className='item' title={`${englishName.of(code)}`} key={`${index}`} data-value={`${code}`} data-detail={`${localName.of(code)}`}>
{`${code}`}
<div className='detail'>{`${localName.of(code)}`}</div>
</div>;
});
};
const debouncedHandleFieldChange = _.debounce(this.handleFieldChange, 500);
return <div className='field language'>
<label>language</label>
<div className='value'>
<Combobox trigger='click'
className='language-dropdown'
default={this.props.metadata.lang || ''}
placeholder='en'
onSelect={(value)=>this.handleLanguage(value)}
onEntry={(e)=>{
e.target.setCustomValidity(''); //Clear the validation popup while typing
debouncedHandleFieldChange('lang', e);
}}
options={listLanguages()}
autoSuggest={{
suggestMethod : 'startsWith',
clearAutoSuggestOnClick : true,
filterOn : ['data-value', 'data-detail', 'title']
}}
>
</Combobox>
<small>Sets the HTML Lang property for your brew. May affect hyphenation or spellcheck.</small>
</div>
</div>;
},
renderRenderOptions : function(){
if(!global.enable_v3) return;
@@ -301,6 +350,8 @@ const MetadataEditor = createClass({
</div>
</div>
{this.renderLanguageDropdown()}
{this.renderThemeDropdown()}
{this.renderRenderOptions()}
@@ -315,7 +366,7 @@ const MetadataEditor = createClass({
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.']}
notes={['Invited author usernames 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/>

View File

@@ -36,11 +36,15 @@
flex: 5 0 200px;
gap: 10px;
}
.field{
display : flex;
flex-wrap : wrap;
width : 100%;
min-width : 200px;
position : relative;
&>label{
width : 80px;
font-size : 11px;
@@ -57,6 +61,9 @@
}
input[type='text'], textarea {
border : 1px solid gray;
&:focus {
outline: 1px solid #444;
}
}
&.thumbnail{
height : 1.4em;
@@ -88,9 +95,15 @@
}
}
&.language .language-dropdown {
max-width : 150px;
z-index : 200;
}
small {
font-size : 0.6em;
font-style : italic;
font-size : 0.6em;
font-style : italic;
line-height : 1.4em;
display : inline-block;
}
}
@@ -159,7 +172,7 @@
.navDropdownContainer {
background-color : white;
position : relative;
z-index : 500;
z-index : 100;
&.disabled {
font-style :italic;
font-style : italic;

View File

@@ -23,9 +23,9 @@ module.exports = {
}
}
],
language : [
lang : [
(value)=>{
return new RegExp(/[a-z]{2,3}(-.*)?/).test(value || '') === false ? 'Invalid language code.' : null;
return new RegExp(/^([a-zA-Z]{2,3})(-[a-zA-Z]{4})?(-(?:[0-9]{3}|[a-zA-Z]{2}))?$/).test(value) === false && (value.length > 0) ? 'Invalid language code.' : null;
}
]
};