Skip to content

Commit 86959e0

Browse files
committed
task: implement AddCatalogPriceForm
Fix #1342
1 parent fb1df42 commit 86959e0

File tree

3 files changed

+155
-4
lines changed

3 files changed

+155
-4
lines changed

Diff for: src/main/frontend/src/components/AddCatalogPriceForm.js

+153-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,162 @@
22
// IMPORTANT:
33
// You must update ResourceUrl.RESOURCES_VERSION each time whenever you're modified this file!
44
//
5+
// @todo #1342 AddCatalogPriceForm: show a currency
56

67
class AddCatalogPriceForm extends React.Component {
7-
8+
constructor(props) {
9+
super(props);
10+
this.state = {
11+
price: null,
12+
catalog: 'michel',
13+
hasServerError: false,
14+
validationErrors: [],
15+
isDisabled: false
16+
};
17+
this.handleSubmit = this.handleSubmit.bind(this);
18+
this.handleChangePrice = this.handleChangePrice.bind(this);
19+
this.handleChangeCatalog = this.handleChangeCatalog.bind(this);
20+
}
21+
22+
handleChangePrice(event) {
23+
event.preventDefault();
24+
this.setState({
25+
price: event.target.value
26+
});
27+
}
28+
29+
handleChangeCatalog(event) {
30+
event.preventDefault();
31+
this.setState({
32+
catalog: event.target.value
33+
});
34+
}
35+
36+
handleSubmit(event) {
37+
event.preventDefault();
38+
39+
this.setState({
40+
isDisabled: true,
41+
hasServerError: false,
42+
validationErrors: []
43+
});
44+
45+
axios.patch(
46+
this.props.url,
47+
[
48+
{
49+
op: 'add',
50+
path: `/${this.state.catalog}_price`,
51+
value: this.state.price
52+
}
53+
],
54+
{
55+
headers: {
56+
[this.props.csrfHeaderName]: this.props.csrfTokenValue,
57+
'Cache-Control': 'no-store'
58+
},
59+
validateStatus: status => {
60+
return status == 204 || status == 400;
61+
}
62+
}
63+
)
64+
.then(response => {
65+
const data = response.data;
66+
if (data.hasOwnProperty('fieldErrors')) {
67+
const fieldErrors = [];
68+
if (data.fieldErrors.price) {
69+
fieldErrors.push(...data.fieldErrors.price);
70+
}
71+
72+
this.setState({
73+
isDisabled: false,
74+
validationErrors: fieldErrors
75+
});
76+
return;
77+
}
78+
79+
// no need to reset the state as page will be reloaded
80+
window.location.reload();
81+
})
82+
.catch(error => {
83+
console.error(error);
84+
this.setState({ isDisabled: false, hasServerError: true });
85+
});
86+
}
887
render() {
88+
const hasValidationErrors = this.state.validationErrors.length > 0;
989
return (
10-
<div></div>
11-
)
90+
<div className="col-sm-12 form-group">
91+
<form className={`form-horizontal ${hasValidationErrors ? 'has-error' : ''}`} onSubmit={this.handleSubmit}>
92+
<div
93+
id="add-catalog-price-failed-msg"
94+
className={`alert alert-danger text-center col-sm-8 col-sm-offset-2 ${this.state.hasServerError ? '' : 'hidden'}`}>
95+
{ this.props.l10n['t_server_error'] || 'Server error' }
96+
</div>
97+
<div className="form-group form-group-sm">
98+
<label className="control-label col-sm-3">
99+
{ this.props.l10n['t_catalog'] || 'Catalog' }
100+
</label>
101+
<div className="col-sm-6">
102+
<select
103+
id="catalog-name"
104+
name="catalogName"
105+
className="form-control"
106+
onChange={this.handleChangeCatalog}>
107+
<option value="michel">
108+
{ this.props.l10n['t_michel'] || 'Michel' }
109+
</option>
110+
<option value="scott">
111+
{ this.props.l10n['t_scott'] || 'Scott' }
112+
</option>
113+
<option value="yvert">
114+
{ this.props.l10n['t_yvert'] || 'Yvert et Tellier' }
115+
</option>
116+
<option value="gibbons">
117+
{ this.props.l10n['t_sg'] || 'Stanley Gibbons' }
118+
</option>
119+
<option value="solovyov">
120+
{ this.props.l10n['t_solovyov'] || 'Solovyov' }
121+
</option>
122+
<option value="zagorski">
123+
{ this.props.l10n['t_zagorski'] || 'Zagorski' }
124+
</option>
125+
</select>
126+
</div>
127+
</div>
128+
<div className="form-group form-group-sm">
129+
<label className="control-label col-sm-3">
130+
{ this.props.l10n['t_price'] || 'Price' }
131+
</label>
132+
<div className="col-sm-6">
133+
<div className="row">
134+
<div className="col-xs-6">
135+
<input
136+
className="form-control"
137+
id="catalog-price"
138+
type="text"
139+
size="5"
140+
required="required"
141+
onChange={ this.handleChangePrice }/>
142+
</div>
143+
</div>
144+
</div>
145+
</div>
146+
<div className="col-sm-offset-3 col-sm-4">
147+
<span
148+
id="catalog-price.errors"
149+
className={`help-block ${hasValidationErrors ? '' : 'hidden'}`}>
150+
{ this.state.validationErrors.join(', ') }
151+
</span>
152+
<button
153+
type="submit"
154+
className="btn btn-primary btn-sm"
155+
disabled={ this.state.isDisabled }>
156+
{ this.props.l10n['t_add'] || 'Add' }
157+
</button>
158+
</div>
159+
</form>
160+
</div>
161+
);
12162
}
13163
}

Diff for: src/main/java/ru/mystamps/web/feature/site/ResourceUrl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public final class ResourceUrl {
3232
public static final String STATIC_RESOURCES_URL = "https://stamps.filezz.ru";
3333

3434
// MUST be updated when any of our resources were modified
35-
public static final String RESOURCES_VERSION = "v0.4.3.1";
35+
public static final String RESOURCES_VERSION = "v0.4.3.2";
3636

3737
// CheckStyle: ignore LineLength for next 14 lines
3838
private static final String CATALOG_UTILS_JS = "/public/js/" + RESOURCES_VERSION + "/CatalogUtils.min.js";

Diff for: src/main/webapp/WEB-INF/views/series/info.html

+1
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,7 @@ <h5 th:text="#{t_add_info_who_selling_series}">Add info about selling/buying thi
931931
'fieldErrors': {
932932
'comment': ['Comment error'],
933933
'year': ['Year error'],
934+
'price': ['Price error']
934935
}
935936
}
936937
},

0 commit comments

Comments
 (0)