Skip to content

Commit 78f598c

Browse files
committed
improve: allow to specify multiple ids or range of ids when adding similar series.
Fix #1448
1 parent d4ee7e7 commit 78f598c

File tree

8 files changed

+62
-24
lines changed

8 files changed

+62
-24
lines changed

src/main/frontend/src/components/SimilarSeriesForm.js

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class SimilarSeriesForm extends React.PureComponent {
1010
super(props);
1111
this.state = {
1212
seriesId: props.seriesId,
13-
similarSeriesId: '',
13+
similarSeriesIds: [],
1414
isDisabled: false,
1515
hasServerError: false,
1616
validationErrors: []
@@ -22,26 +22,30 @@ class SimilarSeriesForm extends React.PureComponent {
2222
handleChange(event) {
2323
event.preventDefault();
2424
this.setState({
25-
similarSeriesId: event.target.value
25+
similarSeriesIds: event.target.value
2626
});
2727
}
2828

2929
handleSubmit(event) {
3030
event.preventDefault();
3131

32+
const similarSeriesIds = CatalogUtils.expandNumbers(this.state.similarSeriesIds)
33+
.split(',')
34+
.map(number => parseInt(number, 10))
35+
.filter(number => !isNaN(number));
36+
3237
this.setState({
38+
similarSeriesIds: similarSeriesIds,
3339
isDisabled: true,
3440
hasServerError: false,
3541
validationErrors: []
3642
});
3743

38-
const similarSeriesId = parseInt(this.state.similarSeriesId, 10) || this.state.similarSeriesId;
39-
4044
axios.post(
4145
this.props.url,
4246
{
4347
'seriesId': this.state.seriesId,
44-
'similarSeriesId': similarSeriesId
48+
'similarSeriesIds': similarSeriesIds
4549
},
4650
{
4751
headers: {
@@ -59,8 +63,8 @@ class SimilarSeriesForm extends React.PureComponent {
5963
if (data.fieldErrors.seriesId) {
6064
fieldErrors.push(...data.fieldErrors.seriesId);
6165
}
62-
if (data.fieldErrors.similarSeriesId) {
63-
fieldErrors.push(...data.fieldErrors.similarSeriesId);
66+
if (data.fieldErrors.similarSeriesIds) {
67+
fieldErrors.push(...data.fieldErrors.similarSeriesIds);
6468
}
6569
this.setState({ isDisabled: false, validationErrors: fieldErrors });
6670
return;
@@ -81,7 +85,7 @@ class SimilarSeriesForm extends React.PureComponent {
8185
l10n={this.props.l10n}
8286
handleChange={this.handleChange}
8387
handleSubmit={this.handleSubmit}
84-
similarSeriesId={this.state.similarSeriesId}
88+
similarSeriesIds={this.state.similarSeriesIds}
8589
isDisabled={this.state.isDisabled}
8690
hasServerError={this.state.hasServerError}
8791
validationErrors={this.state.validationErrors}
@@ -92,7 +96,7 @@ class SimilarSeriesForm extends React.PureComponent {
9296

9397
class SimilarSeriesFormView extends React.PureComponent {
9498
render() {
95-
const {similarSeriesId, hasServerError, isDisabled, validationErrors, handleChange, handleSubmit} = this.props;
99+
const {similarSeriesIds, hasServerError, isDisabled, validationErrors, handleChange, handleSubmit} = this.props;
96100
const hasValidationErrors = validationErrors.length > 0;
97101

98102
return (
@@ -112,8 +116,8 @@ class SimilarSeriesFormView extends React.PureComponent {
112116
type="text"
113117
className="form-control"
114118
required="required"
115-
placeholder={ this.props.l10n['t_similar_series_id'] || 'Similar series ID' }
116-
value={ similarSeriesId }
119+
placeholder={ this.props.l10n['t_similar_series_ids'] || 'Similar series ID(s)' }
120+
value={ similarSeriesIds }
117121
onChange={ handleChange }
118122
disabled={ isDisabled } />
119123
</div>

src/main/java/ru/mystamps/web/feature/series/AddSimilarSeriesForm.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
import lombok.Getter;
2121
import lombok.Setter;
2222

23+
import javax.validation.constraints.NotEmpty;
2324
import javax.validation.constraints.NotNull;
25+
import java.util.Collections;
26+
import java.util.Set;
2427

2528
// @todo #1280 AddSimilarSeriesForm: series and similar series must be different
2629
@Getter
@@ -33,6 +36,34 @@ public class AddSimilarSeriesForm implements AddSimilarSeriesDto {
3336

3437
// @todo #1280 AddSimilarSeriesForm: add integration test for mandatory similarSeriesId
3538
// @todo #1280 AddSimilarSeriesForm: similarSeriesId must exist
36-
@NotNull
39+
// @todo #1448 AddSimilarSeriesForm.similarSeriesId: remove deprecated member
40+
// NOTE: similarSeriesId is deprecated and exist only for backward compatibility
3741
private Integer similarSeriesId;
42+
43+
private Set<Integer> similarSeriesIds;
44+
45+
@NotNull
46+
public Integer getSimilarSeriesId() {
47+
if (similarSeriesId != null) {
48+
return similarSeriesId;
49+
}
50+
51+
if (similarSeriesIds != null && !similarSeriesIds.isEmpty()) {
52+
return similarSeriesIds.iterator().next();
53+
}
54+
55+
return null;
56+
}
57+
58+
// @todo #1448 AddSimilarSeriesForm: add integration test that similarSeriesIds isn't empty
59+
@NotEmpty
60+
public Set<Integer> getSimilarSeriesIds() {
61+
// respect the old interface to not break compatibility
62+
if (similarSeriesId != null) {
63+
return Collections.singleton(similarSeriesId);
64+
}
65+
66+
return similarSeriesIds;
67+
}
68+
3869
}

src/main/java/ru/mystamps/web/feature/series/SeriesController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,9 @@ public ResponseEntity<Void> markSimilarSeries(
626626

627627
} catch (RuntimeException ex) { // NOPMD: AvoidCatchingGenericException; try to catch-all
628628
LOG.error(
629-
"Couldn't mark series #{} similar to #{}: {}",
629+
"Couldn't mark series #{} similar to {}: {}",
630630
form.getSeriesId(),
631-
form.getSimilarSeriesId(),
631+
form.getSimilarSeriesIds(),
632632
ex.getMessage()
633633
);
634634
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);

src/main/java/ru/mystamps/web/feature/series/SeriesServiceImpl.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,12 +428,14 @@ public void markAsSimilar(AddSimilarSeriesForm dto) {
428428
Integer seriesId = dto.getSeriesId();
429429
Validate.isTrue(seriesId != null, "Series id must be non null");
430430

431-
Integer similarSeriesId = dto.getSimilarSeriesId();
432-
Validate.isTrue(similarSeriesId != null, "Similar series id must be non null");
433-
434-
seriesDao.markAsSimilar(seriesId, similarSeriesId);
435-
436-
log.info("Series #{} has been marked as similar to #{}", seriesId, similarSeriesId);
431+
Set<Integer> similarSeriesIds = dto.getSimilarSeriesIds();
432+
Validate.isTrue(similarSeriesIds != null, "Similar series ids must be non null");
433+
434+
// @todo #1448 SeriesServiceImpl.markAsSimilar(): mark multiple series at once in DAO
435+
for (Integer similarSeriesId : similarSeriesIds) {
436+
seriesDao.markAsSimilar(seriesId, similarSeriesId);
437+
log.info("Series #{} has been marked as similar to #{}", seriesId, similarSeriesId);
438+
}
437439
}
438440

439441
private List<SeriesInfoDto> findByCatalogNumber(

src/main/java/ru/mystamps/web/feature/site/ResourceUrl.java

Lines changed: 1 addition & 1 deletion
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.4.0";
35+
public static final String RESOURCES_VERSION = "v0.4.4.1";
3636

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

src/main/resources/ru/mystamps/i18n/Messages.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ t_sold_for = for
169169
t_not_chosen_masculine = Not chosen
170170
t_imported_from = Imported from
171171
t_similar_series = Similar series
172-
t_similar_series_id = Similar series ID
172+
t_similar_series_ids = Similar series ID(s)
173173
t_mark_as_similar = Mark as similar
174174
t_could_not_import_info = Could not import information from this page
175175

src/main/resources/ru/mystamps/i18n/Messages_ru.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ t_sold_for = за
168168
t_not_chosen_masculine = Не выбран
169169
t_imported_from = Импортировано с
170170
t_similar_series = Похожие серии
171-
t_similar_series_id = ID серии
171+
t_similar_series_ids = ID серии(й)
172172
t_mark_as_similar = Отметить как похожую
173173
t_could_not_import_info = Не удалось импортировать информацию с этой страницы
174174

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,7 @@ <h5 th:text="#{t_add_info_who_selling_series}">Add info about selling/buying thi
11401140
<!--/*/
11411141
<th:block sec:authorize="hasAuthority('MARK_SIMILAR_SERIES')">
11421142
/*/-->
1143+
<script src="../../../../javascript/CatalogUtils.js" th:src="${CATALOG_UTILS_JS}"></script>
11431144
<script src="../../../../../../target/classes/js/components/SimilarSeriesForm.js" th:src="${SIMILAR_SERIES_FORM_JS}"></script>
11441145
<script th:inline="javascript">
11451146
/*[+
@@ -1151,7 +1152,7 @@ <h5 th:text="#{t_add_info_who_selling_series}">Add info about selling/buying thi
11511152
'l10n': {
11521153
't_server_error': [[ #{t_server_error} ]],
11531154
't_mark_as_similar': [[ #{t_mark_as_similar} ]],
1154-
't_similar_series_id': [[ #{t_similar_series_id} ]],
1155+
't_similar_series_ids': [[ #{t_similar_series_ids} ]],
11551156
}
11561157
};
11571158
+]*/

0 commit comments

Comments
 (0)