0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-03-22 06:48:11 +00:00

next stable

This commit is contained in:
Víctor Losada Hernández
2026-02-16 00:58:50 +01:00
parent 2a9970705b
commit dec91cc76e
4 changed files with 33 additions and 51 deletions

View File

@@ -16,6 +16,7 @@ const Combobox = createReactClass({
suggestMethod : 'includes',
filterOn : [] // should allow as array to filter on multiple attributes, or even custom filter
},
valuePatterns: [/.+/]
};
},
getInitialState : function() {
@@ -74,6 +75,7 @@ const Combobox = createReactClass({
type='text'
onChange={(e)=>this.handleInput(e)}
value={this.state.value || ''}
pattern={this.props.valuePatterns}
placeholder={this.props.placeholder}
onBlur={(e)=>{
if(!e.target.checkValidity()){
@@ -82,6 +84,12 @@ const Combobox = createReactClass({
});
}
}}
onKeyDown={(e)=>{
if (e.key === "Enter") {
e.preventDefault();
this.props.onEntry(e);
}
}}
/>
<i className='fas fa-caret-down'/>
</div>

View File

@@ -10,8 +10,6 @@ import TagInput from '../tagInput/tagInput.jsx';
import Themes from 'themes/themes.json';
import validations from './validations.js';
const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder'];
import homebreweryThumbnail from '../../thumbnail.png';
const callIfExists = (val, fn, ...args)=>{
@@ -33,7 +31,6 @@ const MetadataEditor = createReactClass({
tags : [],
published : false,
authors : [],
systems : [],
renderer : 'legacy',
theme : '5ePHB',
lang : 'en'
@@ -91,15 +88,6 @@ const MetadataEditor = createReactClass({
}
},
handleSystem : function(system, e){
if(e.target.checked){
this.props.metadata.systems.push(system);
} else {
this.props.metadata.systems = _.without(this.props.metadata.systems, system);
}
this.props.onChange(this.props.metadata);
},
handleRenderer : function(renderer, e){
if(e.target.checked){
this.props.metadata.renderer = renderer;
@@ -155,18 +143,6 @@ const MetadataEditor = createReactClass({
});
},
renderSystems : function(){
return _.map(SYSTEMS, (val)=>{
return <label key={val}>
<input
type='checkbox'
checked={_.includes(this.props.metadata.systems, val)}
onChange={(e)=>this.handleSystem(val, e)} />
{val}
</label>;
});
},
renderPublish : function(){
if(this.props.metadata.published){
return <button className='unpublish' onClick={()=>this.handlePublish(false)}>
@@ -304,7 +280,7 @@ const MetadataEditor = createReactClass({
},
renderRenderOptions : function(){
return <div className='field systems'>
return <div className='field renderers'>
<label>Renderer</label>
<div className='value'>
<label key='legacy'>
@@ -363,19 +339,12 @@ const MetadataEditor = createReactClass({
{this.renderThumbnail()}
</div>
<TagInput label='tags' valuePatterns={[/^(?:(?:group|meta|system|type):)?[A-Za-z0-9][A-Za-z0-9 \/.\-]{0,40}$/]}
<TagInput label='tags' valuePatterns={/^(?:(?:group|meta|system|type):)?[A-Za-z0-9][A-Za-z0-9 \/.\-]{0,40}$/}
placeholder='add tag' unique={true}
values={this.props.metadata.tags}
onChange={(e)=>this.handleFieldChange('tags', e)}
/>
<div className='field systems'>
<label>systems</label>
<div className='value'>
{this.renderSystems()}
</div>
</div>
{this.renderLanguageDropdown()}
{this.renderThemeDropdown()}
@@ -386,7 +355,7 @@ const MetadataEditor = createReactClass({
{this.renderAuthors()}
<TagInput label='invited authors' valuePatterns={[/.+/]}
<TagInput label='invited authors' valuePatterns={/.+/}
validators={[(v)=>!this.props.metadata.authors?.includes(v)]}
placeholder='invite author' unique={true}
values={this.props.metadata.invitedAuthors}

View File

@@ -134,7 +134,7 @@
background-color : #AAAAAA;
}
.systems.field .value {
.renderers.field .value {
label {
display : inline-flex;
align-items : center;

View File

@@ -4,7 +4,7 @@ import Combobox from "../../../components/combobox.jsx";
import tagSuggestionList from "./curatedTagSuggestionList.js";
const TagInput = ({ label, unique = true, values = [], placeholder = "", onChange }) => {
const TagInput = ({ label, valuePatterns, values = [], unique = true, placeholder = "", onChange }) => {
const [tagList, setTagList] = useState(
values.map((value) => ({
value,
@@ -51,19 +51,27 @@ const TagInput = ({ label, unique = true, values = [], placeholder = "", onChang
const normalizeValue = (input) => {
const lowerInput = input.toLowerCase();
const group = duplicateGroups.find((grp) => grp.some((tag) => tag && lowerInput.includes(tag.toLowerCase())));
return group ? group[0] : input;
};
const regexPattern =
label === "tags"
? /^[-A-Za-z0-9&_.()]+$/ // only allowed chars for tags
: /^.*$/; // allow all characters otherwise
for (const group of duplicateGroups) {
for (const tag of group) {
if (!tag) continue;
const index = lowerInput.indexOf(tag.toLowerCase());
if (index !== -1) {
return input.slice(0, index) + group[0] + input.slice(index + tag.length);
}
}
}
return input;
};
const submitTag = (newValue, index = null) => {
const trimmed = newValue?.trim();
console.log(newValue, trimmed);
if (!trimmed) return;
if (!regexPattern.test(trimmed)) return;
console.log(valuePatterns.test(trimmed));
if (!valuePatterns.test(trimmed)) return;
const canonical = normalizeValue(trimmed);
@@ -117,12 +125,7 @@ const TagInput = ({ label, unique = true, values = [], placeholder = "", onChang
}
return (
<div
className={classes}
key={`tag-${tag}`} // unique key
value={tag}
data={tag}
title={tag}>
<div className={classes} key={`tag-${tag}`} value={tag} data={tag} title={tag}>
{tag}
</div>
);
@@ -140,7 +143,7 @@ const TagInput = ({ label, unique = true, values = [], placeholder = "", onChang
key={i}
type="text"
value={t.display}
pattern="[-A-Za-z0-9&_.()]+"
pattern={valuePatterns.source}
onChange={(e) => {
const val = e.target.value;
setTagList((prev) =>
@@ -186,9 +189,11 @@ const TagInput = ({ label, unique = true, values = [], placeholder = "", onChang
}
: { suggestMethod: "includes", clearAutoSuggestOnClick: true, filterOn: [] } // empty filter
}
valuePatterns={valuePatterns.source}
onSelect={(value) => submitTag(value)}
onEntry={(e) => {
if (e.key === "Enter") {
console.log("submit");
e.preventDefault();
submitTag(e.target.value);
}