@luomus/laji-form 15.1.66 → 15.1.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/laji-form.js +1 -1
  2. package/lib/ApiClient.d.ts +66 -21
  3. package/lib/ApiClient.js +174 -68
  4. package/lib/components/LajiForm.js +1 -1
  5. package/lib/components/fields/AnnotationField.js +26 -22
  6. package/lib/components/fields/AudioArrayField.js +18 -5
  7. package/lib/components/fields/AutosuggestField.d.ts +2 -2
  8. package/lib/components/fields/AutosuggestField.js +4 -4
  9. package/lib/components/fields/EnumRangeArrayField.js +1 -1
  10. package/lib/components/fields/GeocoderField.js +2 -9
  11. package/lib/components/fields/ImageArrayField.d.ts +2 -2
  12. package/lib/components/fields/ImageArrayField.js +82 -112
  13. package/lib/components/fields/MapArrayField.js +13 -5
  14. package/lib/components/fields/MapField.d.ts +1 -1
  15. package/lib/components/fields/MapField.js +13 -5
  16. package/lib/components/fields/NamedPlaceChooserField/NamedPlaceChooser.d.ts +2 -1
  17. package/lib/components/fields/NamedPlaceChooserField/NamedPlaceChooserField.d.ts +9 -4
  18. package/lib/components/fields/NamedPlaceChooserField/NamedPlaceChooserField.js +51 -51
  19. package/lib/components/fields/NamedPlaceChooserField/Popup.d.ts +2 -1
  20. package/lib/components/fields/NamedPlaceSaverField.js +22 -18
  21. package/lib/components/fields/ScopeField.js +1 -1
  22. package/lib/components/fields/SingleActiveArrayField.js +2 -2
  23. package/lib/components/fields/SortArrayField.js +1 -1
  24. package/lib/components/fields/UnitCountShorthandField.js +1 -1
  25. package/lib/components/fields/UnitListShorthandArrayField.js +2 -2
  26. package/lib/components/fields/UnitShorthandField.js +14 -18
  27. package/lib/components/widgets/AutosuggestWidget.js +79 -66
  28. package/lib/components/widgets/InformalTaxonGroupChooserWidget.js +1 -1
  29. package/lib/components/widgets/InputWithDefaultValueButtonWidget.js +1 -2
  30. package/lib/validation.js +1 -1
  31. package/package.json +5 -3
@@ -911,13 +911,13 @@ const headerFormatters = {
911
911
  this.fetch = (props) => {
912
912
  const { namedPlaceID } = (props.that.props.formData || {})[props.idx] || {};
913
913
  if (namedPlaceID)
914
- props.that.props.formContext.apiClient.fetchCached(`/named-places/${namedPlaceID}`, undefined, { failSilently: true }).then(response => {
914
+ props.that.props.formContext.apiClient.get("/named-places/{id}", { path: { id: namedPlaceID } }).then(response => {
915
915
  if (this.mounted && response.name !== this.state.name)
916
916
  this.setState({
917
917
  namedPlaceID,
918
918
  name: response.name
919
919
  });
920
- });
920
+ }).catch(() => { });
921
921
  };
922
922
  this.state = {};
923
923
  }
@@ -69,7 +69,7 @@ class TaxonomicComparer extends Comparer {
69
69
  }
70
70
  initialize() {
71
71
  return __awaiter(this, void 0, void 0, function* () {
72
- this.idToIdx = (yield this.formContext.apiClient.fetchCached("/taxa", Object.assign(Object.assign({}, this.options.query), { pageSize: 10000, selectedFields: "id" })))
72
+ this.idToIdx = (yield this.formContext.apiClient.get("/taxa", { query: Object.assign(Object.assign({}, this.options.query), { pageSize: 10000, selectedFields: "id" }) }))
73
73
  .results.reduce((idToIdx, { id }, idx) => {
74
74
  idToIdx[id] = idx;
75
75
  return idToIdx;
@@ -82,7 +82,7 @@ let UnitCountShorthandField = class UnitCountShorthandField extends React.Compon
82
82
  resolve({ success: undefined });
83
83
  return;
84
84
  }
85
- apiClient.fetchCached("/autocomplete/pairCount", { q: value, taxonID: taxonId }).then(suggestion => {
85
+ apiClient.get("/shorthand/unit/water-bird-pair-count", { query: { query: value, taxonID: taxonId } }).then(suggestion => {
86
86
  if (timestamp !== this.promiseTimestamp) {
87
87
  reject();
88
88
  return;
@@ -69,8 +69,8 @@ let UnitListShorthandArrayField = class UnitListShorthandArrayField extends Reac
69
69
  this.onHide();
70
70
  const { translations, notifier, apiClient } = this.props.formContext;
71
71
  this.props.formContext.services.blocker.push();
72
- apiClient.fetch("/autocomplete/unit", { q: value, list: true, includePayload: true }).then(({ payload: { units, nonMatchingCount } }) => {
73
- units = units.map(unit => {
72
+ apiClient.get("/shorthand/unit/list", { query: { query: value } }).then(({ results, nonMatchingCount }) => {
73
+ const units = results.map(unit => {
74
74
  unit = (0, utils_1.getDefaultFormState)(this.props.schema.items, unit);
75
75
  unit = (0, utils_1.bringRemoteFormData)(unit, this.props.formContext);
76
76
  unit = (0, utils_1.assignUUID)(unit);
@@ -51,7 +51,6 @@ const ReactContext_1 = __importDefault(require("../../ReactContext"));
51
51
  const components_1 = require("../components");
52
52
  const AutosuggestWidget_1 = require("../widgets/AutosuggestWidget");
53
53
  const ArrayFieldTemplate_1 = require("../templates/ArrayFieldTemplate");
54
- const LINE_TRANSECT_IDS = ["MHL.1", "MHL.27", "MHL.28"];
55
54
  let UnitShorthandField = class UnitShorthandField extends React.Component {
56
55
  constructor(props) {
57
56
  super(props);
@@ -125,13 +124,13 @@ let UnitShorthandField = class UnitShorthandField extends React.Component {
125
124
  render() {
126
125
  const { uiSchema, formContext, disabled, readonly } = this.props;
127
126
  const { SchemaField } = this.props.registry.fields;
128
- const shorthandFieldName = (0, utils_1.getUiOptions)(this.props.uiSchema).shorthandField;
127
+ const { shorthandField, lineTransect } = (0, utils_1.getUiOptions)(this.props.uiSchema);
129
128
  const toggleButton = this.getToggleButton();
130
129
  const tailUiSchema = (0, utils_1.getNestedTailUiSchema)(uiSchema);
131
- let help = tailUiSchema && tailUiSchema[shorthandFieldName] && tailUiSchema[shorthandFieldName]["ui:belowHelp"];
132
- const uiSchemaWithoutHelp = (0, utils_1.isEmptyString)(help) ? uiSchema : (0, utils_1.updateTailUiSchema)(uiSchema, { [shorthandFieldName]: { "ui:belowHelp": { $set: undefined } } });
133
- const id = (shorthandFieldName && this.props.idSchema[shorthandFieldName]) ?
134
- this.props.idSchema[shorthandFieldName].$id :
130
+ let help = tailUiSchema && tailUiSchema[shorthandField] && tailUiSchema[shorthandField]["ui:belowHelp"];
131
+ const uiSchemaWithoutHelp = (0, utils_1.isEmptyString)(help) ? uiSchema : (0, utils_1.updateTailUiSchema)(uiSchema, { [shorthandField]: { "ui:belowHelp": { $set: undefined } } });
132
+ const id = (shorthandField && this.props.idSchema[shorthandField]) ?
133
+ this.props.idSchema[shorthandField].$id :
135
134
  `${this.props.idSchema.$id}_shortHandField`;
136
135
  let innerUiSchema = undefined;
137
136
  if (this.state.showSchema) {
@@ -140,7 +139,7 @@ let UnitShorthandField = class UnitShorthandField extends React.Component {
140
139
  innerUiSchema = Object.assign(Object.assign({}, innerUiSchema), { "ui:options": Object.assign(Object.assign({}, innerOptions), { buttons: [...(innerOptions.buttons || []), toggleButton] }) });
141
140
  }
142
141
  return !this.state.showSchema ? (React.createElement("div", { className: "laji-form-field-template-item", id: `_laji-form_${id}` },
143
- React.createElement(CodeReader, { translations: this.props.formContext.translations, onChange: this.onCodeChange, value: this.props.formData[shorthandFieldName], formID: (0, utils_1.getUiOptions)(this.props.uiSchema).formID || formContext.formID || formContext.uiSchemaContext.formID, help: help, id: id, formContext: formContext, disabled: disabled, readonly: readonly, className: "laji-form-field-template-schema" }),
142
+ React.createElement(CodeReader, { translations: this.props.formContext.translations, onChange: this.onCodeChange, value: this.props.formData[shorthandField], formID: (0, utils_1.getUiOptions)(this.props.uiSchema).formID || formContext.formID || formContext.uiSchemaContext.formID, help: help, id: id, formContext: formContext, disabled: disabled, readonly: readonly, lineTransect: lineTransect, className: "laji-form-field-template-schema" }),
144
143
  React.createElement("div", { className: "laji-form-field-template-buttons" }, (0, ArrayFieldTemplate_1.getButton)(toggleButton)))) : (React.createElement(SchemaField, Object.assign({}, this.props, { uiSchema: innerUiSchema })));
145
144
  }
146
145
  };
@@ -185,14 +184,14 @@ let CodeReader = class CodeReader extends React.Component {
185
184
  this.onAutosuggestChange = (formData) => {
186
185
  this.props.onChange(formData);
187
186
  };
188
- this.onSuggestionSelected = ({ payload: { unit } }) => {
187
+ this.onSuggestionSelected = ({ unit }) => {
189
188
  const { formContext } = this.props;
190
189
  unit = (0, utils_1.bringRemoteFormData)(unit, formContext);
191
190
  this.props.onChange(unit);
192
191
  };
193
192
  this.renderSuggestion = (suggestion) => {
194
193
  const { translations } = this.props;
195
- return suggestion.payload.isNonMatching
194
+ return suggestion.isNonMatching
196
195
  ? React.createElement("span", { className: "text-muted" },
197
196
  suggestion.value,
198
197
  " ",
@@ -212,8 +211,8 @@ let CodeReader = class CodeReader extends React.Component {
212
211
  }
213
212
  else if (value.length >= 3) {
214
213
  this.mounted && this.setState({ loading: true });
215
- this.apiClient.fetchCached("/autocomplete/unit", { q: value, formID: this.props.formID, includePayload: true }).then(response => {
216
- this.props.onChange(response.payload.unit);
214
+ this.apiClient.get("/shorthand/unit/line-transect", { query: { query: value } }).then(response => {
215
+ this.props.onChange(response.unit);
217
216
  }).catch(() => {
218
217
  this.mounted && this.setState({ failed: true, loading: false });
219
218
  });
@@ -230,18 +229,15 @@ let CodeReader = class CodeReader extends React.Component {
230
229
  this.mounted = false;
231
230
  }
232
231
  render() {
233
- const { translations, readonly, disabled } = this.props;
232
+ const { translations, readonly, disabled, lineTransect } = this.props;
234
233
  let validationState = null;
235
234
  if (this.state.failed === true)
236
235
  validationState = "warning";
237
236
  else if (!(0, utils_1.isEmptyString)(this.props.value) && this.props.value === this.state.value)
238
237
  validationState = "success";
239
- const { formID, formContext } = this.props;
240
- const inputElem = LINE_TRANSECT_IDS.includes(formID) ? (React.createElement(components_1.FetcherInput, { id: this.props.id, loading: this.state.loading, value: this.state.value, validationState: validationState, onChange: this.onFetcherInputChange, onBlur: this.getCode, onKeyDown: this.onKeyDown, readonly: readonly, disabled: disabled })) : (React.createElement("div", { className: "unit-shorthand" },
241
- React.createElement(AutosuggestWidget_1.Autosuggest, { autosuggestField: "unit", query: {
242
- formID,
243
- includeNonMatching: true
244
- }, onSuggestionSelected: this.onSuggestionSelected, renderSuggestion: this.renderSuggestion, onChange: this.onAutosuggestChange, formContext: formContext, allowNonsuggestedValue: false })));
238
+ const { formContext } = this.props;
239
+ const inputElem = lineTransect ? (React.createElement(components_1.FetcherInput, { id: this.props.id, loading: this.state.loading, value: this.state.value, validationState: validationState, onChange: this.onFetcherInputChange, onBlur: this.getCode, onKeyDown: this.onKeyDown, readonly: readonly, disabled: disabled })) : (React.createElement("div", { className: "unit-shorthand" },
240
+ React.createElement(AutosuggestWidget_1.Autosuggest, { autosuggestField: "unit", onSuggestionSelected: this.onSuggestionSelected, renderSuggestion: this.renderSuggestion, onChange: this.onAutosuggestChange, formContext: formContext, allowNonsuggestedValue: false })));
245
241
  const { FormGroup, HelpBlock } = this.context.theme;
246
242
  return (React.createElement(FormGroup, { validationState: this.state.failed ? "error" : undefined },
247
243
  inputElem,
@@ -38,6 +38,15 @@ var __importStar = (this && this.__importStar) || (function () {
38
38
  return result;
39
39
  };
40
40
  })();
41
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
42
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
43
+ return new (P || (P = Promise))(function (resolve, reject) {
44
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
45
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
46
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
47
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
48
+ });
49
+ };
41
50
  var __rest = (this && this.__rest) || function (s, e) {
42
51
  var t = {};
43
52
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -63,7 +72,7 @@ const components_1 = require("../components");
63
72
  const ReactContext_1 = __importDefault(require("../../ReactContext"));
64
73
  const InformalTaxonGroupChooserWidget_1 = require("./InformalTaxonGroupChooserWidget");
65
74
  function renderFlag(suggestion, prepend) {
66
- return (suggestion && suggestion.payload || {}).finnish
75
+ return (suggestion || {}).finnish
67
76
  ? React.createElement(React.Fragment, null,
68
77
  prepend || null,
69
78
  React.createElement("img", { src: "https://cdn.laji.fi/images/icons/flag_fi_small.png", width: "16" }))
@@ -73,10 +82,11 @@ class _AutosuggestWidget extends React.Component {
73
82
  render() {
74
83
  if (this.props.options) {
75
84
  switch (this.props.options.autosuggestField) {
85
+ case "taxa":
76
86
  case "taxon":
77
- return React.createElement(TaxonAutosuggestWidget, Object.assign({}, this.props));
87
+ return React.createElement(TaxonAutosuggestWidget, Object.assign({}, this.props, { options: Object.assign(Object.assign({}, this.props.options), { autosuggestField: "taxa" }) }));
78
88
  case "unit":
79
- return React.createElement(UnitAutosuggestWidget, Object.assign({}, this.props));
89
+ return React.createElement(UnitAutosuggestWidget, Object.assign({}, this.props, { basePath: "/shorthand/unit/trip-report" }));
80
90
  case "friends":
81
91
  case "person":
82
92
  return React.createElement(FriendsAutosuggestWidget, Object.assign({}, this.props));
@@ -97,6 +107,7 @@ class _AutosuggestWidget extends React.Component {
97
107
  let component = undefined;
98
108
  switch (options.autosuggestField) {
99
109
  case "taxon":
110
+ case "taxa":
100
111
  component = TaxonAutosuggestWidget;
101
112
  break;
102
113
  case "unit":
@@ -176,11 +187,7 @@ function TaxonAutosuggest(ComposedComponent) {
176
187
  orWriteSpeciesNameLabel || this.props.formContext.translations.orWriteSpeciesName))));
177
188
  };
178
189
  this.onTaxonImgSelected = (taxonID, taxon) => {
179
- this.autosuggestRef.selectSuggestion({
180
- key: taxonID,
181
- value: taxon.vernacularName,
182
- payload: taxon
183
- });
190
+ this.autosuggestRef.selectSuggestion(Object.assign({ key: taxonID, value: taxon.vernacularName }, taxon));
184
191
  };
185
192
  this.setAutosuggestRef = (elem) => {
186
193
  this.autosuggestRef = elem;
@@ -212,19 +219,20 @@ function TaxonAutosuggest(ComposedComponent) {
212
219
  }
213
220
  }
214
221
  getSuggestionFromValue(value) {
215
- if (this.isValueSuggested(value)) {
216
- return this.props.formContext.apiClient.fetchCached(`/taxa/${value}`).then(({ vernacularName, scientificName }) => {
222
+ return __awaiter(this, void 0, void 0, function* () {
223
+ if (this.isValueSuggested(value)) {
224
+ const { vernacularName, scientificName } = yield this.props.formContext.apiClient.get(`/taxa/${id}`);
217
225
  if (vernacularName !== undefined) {
218
226
  return { value: vernacularName, key: value };
219
227
  }
220
228
  if (scientificName !== undefined) {
221
229
  return { value: scientificName, key: value };
222
230
  }
223
- });
224
- }
225
- else {
226
- return Promise.reject();
227
- }
231
+ }
232
+ else {
233
+ throw new Error("Unknown taxon");
234
+ }
235
+ });
228
236
  }
229
237
  isValueSuggested(value) {
230
238
  return !(0, utils_1.isEmptyString)(value) && !!value.match(/MX\.\d+/);
@@ -272,10 +280,10 @@ let UnitAutosuggestWidget = class UnitAutosuggestWidget extends React.Component
272
280
  this.renderSuggestion = this.renderSuggestion.bind(this);
273
281
  }
274
282
  renderSuggestion(suggestion) {
275
- const { count, maleIndividualCount, femaleIndividualCount } = suggestion.payload.interpretedFrom;
283
+ const { count, maleIndividualCount, femaleIndividualCount } = suggestion.interpretedFrom;
276
284
  const [countElem, maleElem, femaleElem] = [count, maleIndividualCount, femaleIndividualCount].map(val => val && React.createElement("span", { className: "text-muted" }, val));
277
- const taxonName = suggestion.payload.unit.identifications[0].taxon;
278
- const name = suggestion.payload.isNonMatching
285
+ const taxonName = suggestion.unit.identifications[0].taxon;
286
+ const name = suggestion.isNonMatching
279
287
  ? React.createElement("span", { className: "text-muted" },
280
288
  taxonName,
281
289
  " ",
@@ -318,10 +326,11 @@ class FriendsAutosuggestWidget extends React.Component {
318
326
  this.isValueSuggested = this.isValueSuggested.bind(this);
319
327
  }
320
328
  getSuggestionFromValue(value) {
321
- const { showID } = (0, utils_1.getUiOptions)(this.props);
322
- const { isAdmin } = this.props.formContext.uiSchemaContext;
323
- if (this.isValueSuggested(value)) {
324
- return this.props.formContext.apiClient.fetchCached(`/person/by-id/${value}`).then(({ fullName, group, id }) => {
329
+ return __awaiter(this, void 0, void 0, function* () {
330
+ const { showID } = (0, utils_1.getUiOptions)(this.props);
331
+ const { isAdmin } = this.props.formContext.uiSchemaContext;
332
+ if (this.isValueSuggested(value)) {
333
+ const { fullName, group, id } = yield this.props.formContext.apiClient.get(`/person/by-id/${value}`);
325
334
  if (fullName) {
326
335
  const addGroup = str => group ? `${str} (${group})` : str;
327
336
  const addID = str => isAdmin && showID ? `${str} (${id})` : str;
@@ -330,11 +339,11 @@ class FriendsAutosuggestWidget extends React.Component {
330
339
  key: value
331
340
  };
332
341
  }
333
- });
334
- }
335
- else {
336
- return Promise.reject();
337
- }
342
+ }
343
+ else {
344
+ throw new Error("Unknown friend");
345
+ }
346
+ });
338
347
  }
339
348
  isValueSuggested(value) {
340
349
  return !(0, utils_1.isEmptyString)(value) && value.match(/MA\.\d+/);
@@ -382,22 +391,21 @@ class BasicAutosuggestWidget extends React.Component {
382
391
  this.isValueSuggested = this.isValueSuggested.bind(this);
383
392
  }
384
393
  getSuggestionFromValue(value) {
385
- const { autosuggestField, nameField } = this.props;
386
- if (this.isValueSuggested(value)) {
387
- const apiClient = this.props.formContext.apiClient;
388
- const fetch = (this.props.cache ? apiClient.fetchCached : apiClient.fetch).bind(apiClient);
389
- return fetch(`/${autosuggestField}/by-id/${value}`).then(result => {
394
+ return __awaiter(this, void 0, void 0, function* () {
395
+ const { autosuggestField, nameField } = this.props;
396
+ if (this.isValueSuggested(value)) {
397
+ const result = yield this.props.formContext.apiClient.get(`/${autosuggestField}/by-id/${value}`, undefined, this.props.cache);
390
398
  if (result[nameField]) {
391
399
  return {
392
400
  value: result[nameField],
393
401
  key: value
394
402
  };
395
403
  }
396
- });
397
- }
398
- else {
399
- return Promise.reject();
400
- }
404
+ }
405
+ else {
406
+ throw new Error("Not autosuggested value");
407
+ }
408
+ });
401
409
  }
402
410
  isValueSuggested(value) {
403
411
  const regexp = new RegExp(this.props.validValueRegexp);
@@ -536,12 +544,12 @@ class Autosuggest extends React.Component {
536
544
  const { findExactMatch } = this.props;
537
545
  return findExactMatch
538
546
  ? findExactMatch(suggestions, inputValue)
539
- : suggestions.find(suggestion => (suggestion && suggestion.value.toLowerCase() === inputValue.trim().toLowerCase() && (!suggestion.payload || !suggestion.payload.isNonMatching)));
547
+ : suggestions.find(suggestion => (suggestion && suggestion.value.toLowerCase() === inputValue.trim().toLowerCase() && !suggestion.isNonMatching));
540
548
  };
541
549
  this.findTheOnlyOneMatch = (suggestions) => {
542
550
  if (!Array.isArray(suggestions))
543
551
  suggestions = [suggestions];
544
- const filtered = suggestions.filter(suggestion => !suggestion || !suggestion.payload || !suggestion.payload.isNonMatching);
552
+ const filtered = suggestions.filter(suggestion => !suggestion || !suggestion.isNonMatching);
545
553
  if (filtered.length === 1) {
546
554
  return filtered[0];
547
555
  }
@@ -549,7 +557,7 @@ class Autosuggest extends React.Component {
549
557
  this.findNonMatching = (suggestions) => {
550
558
  if (!Array.isArray(suggestions))
551
559
  suggestions = [suggestions];
552
- const filtered = suggestions.filter(suggestion => suggestion && suggestion.payload && suggestion.payload.isNonMatching);
560
+ const filtered = suggestions.filter(suggestion => suggestion && suggestion.isNonMatching);
553
561
  if (filtered.length === 1) {
554
562
  return filtered[0];
555
563
  }
@@ -572,11 +580,15 @@ class Autosuggest extends React.Component {
572
580
  }
573
581
  const { autosuggestField, query = {} } = this.props;
574
582
  this.setState({ isLoading: true });
575
- const request = () => {
583
+ const request = () => __awaiter(this, void 0, void 0, function* () {
576
584
  let timestamp = Date.now();
577
585
  this.promiseTimestamp = timestamp;
578
- const fetch = (this.props.cache ? this.apiClient.fetchCached : this.apiClient.fetch).bind(this.apiClient);
579
- fetch("/autocomplete/" + autosuggestField, Object.assign({ q: value, includePayload: true, matchType: "exact,partial", includeHidden: false }, query)).then(suggestions => {
586
+ try {
587
+ let suggestionsResponse = yield this.apiClient.get(this.props.basePath || "/autocomplete" + "/" + autosuggestField, { query: Object.assign({
588
+ // Hack for laji-form in Kotka, since it uses API that isn't laji-api and q was renamed to query in laji-api
589
+ q: value, query: value, matchType: "exact,partial", includeHidden: false }, query) }, this.props.cache);
590
+ // Hack for laji-form in Kotka, since it uses API that isn't laji-api and might have different response signature.
591
+ let suggestions = Array.isArray(suggestionsResponse) ? suggestionsResponse : suggestionsResponse.results;
580
592
  if (this.props.prepareSuggestion) {
581
593
  suggestions = suggestions.map(s => this.props.prepareSuggestion(s));
582
594
  }
@@ -586,12 +598,13 @@ class Autosuggest extends React.Component {
586
598
  this.mounted
587
599
  ? this.setState({ isLoading: false, suggestions }, () => this.afterBlurAndFetch(suggestions))
588
600
  : this.afterBlurAndFetch(suggestions);
589
- }).catch(() => {
601
+ }
602
+ catch (e) {
590
603
  this.mounted
591
604
  ? this.setState({ isLoading: false }, this.afterBlurAndFetch)
592
605
  : this.afterBlurAndFetch();
593
- });
594
- };
606
+ }
607
+ });
595
608
  if (this.timeout) {
596
609
  clearTimeout(this.timeout);
597
610
  }
@@ -802,10 +815,10 @@ class Autosuggest extends React.Component {
802
815
  ? this.props.highlightFirstSuggestion
803
816
  : !this.props.allowNonsuggestedValue;
804
817
  const { renderExtra } = props;
805
- return (React.createElement(React.Fragment, null,
818
+ return React.createElement(React.Fragment, null,
806
819
  renderExtra && renderExtra(),
807
820
  React.createElement("div", { className: (0, utils_1.classNames)("autosuggest-wrapper", props.wrapperClassName) },
808
- React.createElement(ReactAutosuggest, { id: `${this.props.id}-autosuggest`, inputProps: inputProps, renderInputComponent: this.renderInput, suggestions: suggestions, renderSuggestion: this.renderSuggestion, onSuggestionsFetchRequested: this.onSuggestionsFetchRequested, onSuggestionsClearRequested: this.onSuggestionsClearRequested, onSuggestionSelected: this.onSuggestionSelected, onUnsuggestedSelected: this.onUnsuggestedSelected, highlightFirstSuggestion: highlightFirstSuggestion, suggestionsOpenOnFocus: !this.isSuggested(), theme: cssClasses, formContext: this.props.formContext, ref: this.setRef }))));
821
+ React.createElement(ReactAutosuggest, { id: `${this.props.id}-autosuggest`, inputProps: inputProps, renderInputComponent: this.renderInput, suggestions: suggestions, renderSuggestion: this.renderSuggestion, onSuggestionsFetchRequested: this.onSuggestionsFetchRequested, onSuggestionsClearRequested: this.onSuggestionsClearRequested, onSuggestionSelected: this.onSuggestionSelected, onUnsuggestedSelected: this.onUnsuggestedSelected, highlightFirstSuggestion: highlightFirstSuggestion, suggestionsOpenOnFocus: !this.isSuggested(), theme: cssClasses, formContext: this.props.formContext, ref: this.setRef })));
809
822
  }
810
823
  }
811
824
  exports.Autosuggest = Autosuggest;
@@ -842,21 +855,22 @@ class _TaxonWrapper extends React.Component {
842
855
  this.fetch(value);
843
856
  }
844
857
  fetch(value) {
845
- if (!value) {
846
- this.setState({ scientificName: "", cursiveName: false });
847
- }
848
- else {
849
- this.props.formContext.apiClient.fetchCached(`/taxa/${value}`).then(({ scientificName, cursiveName, vernacularName, taxonRank, informalTaxonGroups, finnish }) => {
850
- if (!this.mounted)
851
- return;
852
- this.setState({ value, taxonRank, informalTaxonGroups, taxon: { scientificName, vernacularName, cursiveName, finnish } });
853
- (0, InformalTaxonGroupChooserWidget_1.getInformalGroups)(this.props.formContext.apiClient).then(({ informalTaxonGroupsById }) => {
858
+ return __awaiter(this, void 0, void 0, function* () {
859
+ if (!value) {
860
+ this.setState({ scientificName: "", cursiveName: false });
861
+ }
862
+ else {
863
+ this.props.formContext.apiClient.get(`/taxa/${value}`).then(({ scientificName, cursiveName, vernacularName, taxonRank, informalGroups, finnish }) => {
854
864
  if (!this.mounted)
855
865
  return;
856
- this.setState({ informalTaxonGroupsById });
866
+ this.setState({ value, taxonRank, informalTaxonGroups: informalGroups, taxon: { scientificName, vernacularName, cursiveName, finnish } });
867
+ (0, InformalTaxonGroupChooserWidget_1.getInformalGroups)(this.props.formContext.apiClient).then(({ informalTaxonGroupsById }) => {
868
+ if (!this.mounted)
869
+ return;
870
+ this.setState({ informalTaxonGroupsById });
871
+ });
857
872
  });
858
- });
859
- this.props.formContext.apiClient.fetchCached(`/taxa/${value}/parents`).then(parents => {
873
+ const parents = (yield this.props.formContext.apiClient.get(`/taxa/${value}/parents`)).results;
860
874
  if (!this.mounted)
861
875
  return;
862
876
  const state = { order: undefined, family: undefined };
@@ -874,13 +888,12 @@ class _TaxonWrapper extends React.Component {
874
888
  }
875
889
  }
876
890
  this.setState(Object.assign(Object.assign({}, state), { higherThanOrder: !state.order && !state.family }));
877
- });
878
- this.props.formContext.apiClient.fetchCached("/metadata/ranges/MX.taxonRankEnum").then(taxonRanks => {
891
+ const taxonRanks = yield this.props.formContext.apiClient.get("/metadata/ranges/MX.taxonRankEnum");
879
892
  if (!this.mounted)
880
893
  return;
881
894
  this.setState({ taxonRanks: (0, utils_1.dictionarify)(taxonRanks, function getKey(rank) { return rank.id; }, function getValue(rank) { return rank.value; }) });
882
- });
883
- }
895
+ }
896
+ });
884
897
  }
885
898
  render() {
886
899
  const { id, formContext, value, children, placement, inputValue, isSuggested } = this.props;
@@ -995,7 +1008,7 @@ class TaxonImgChooser extends React.Component {
995
1008
  }
996
1009
  componentDidMount() {
997
1010
  this.mounted = true;
998
- this.props.formContext.apiClient.fetchCached(`/taxa/${this.props.id}`, { includeMedia: true }).then(taxon => {
1011
+ this.props.formContext.apiClient.get(`/taxa/${this.props.id}`, { query: { includeMedia: true } }).then(taxon => {
999
1012
  if (!this.mounted)
1000
1013
  return;
1001
1014
  if (taxon.multimedia && taxon.multimedia.length) {
@@ -1042,7 +1055,7 @@ const TaxonName = ({ scientificName, vernacularName = "", cursiveName, finnish }
1042
1055
  return (React.createElement(React.Fragment, null,
1043
1056
  `${vernacularName}${vernacularName ? " " : ""}`,
1044
1057
  cursiveName ? React.createElement("i", null, _scientificName) : _scientificName,
1045
- renderFlag({ payload: { finnish } }, " ")));
1058
+ renderFlag({ finnish }, " ")));
1046
1059
  };
1047
1060
  class ReactAutosuggest extends React.Component {
1048
1061
  constructor(props) {
@@ -161,7 +161,7 @@ function getInformalGroups(apiClient) {
161
161
  if (informalTaxonGroups) {
162
162
  return Promise.resolve({ informalTaxonGroups, informalTaxonGroupsById });
163
163
  }
164
- return apiClient.fetchCached("/informal-taxon-groups/tree").then(response => {
164
+ return apiClient.get("/informal-taxon-groups/tree").then(response => {
165
165
  // Contains the current taxon group.
166
166
  const informalTaxonGroups = mapGroupsById(response.results);
167
167
  // Contains all groups in flat object.
@@ -54,9 +54,8 @@ class InputWithDefaultValueButtonWidget extends React.Component {
54
54
  else if (apiQueryForDefaultValue) {
55
55
  const { path, query = {}, resultKey, cache = false } = apiQueryForDefaultValue;
56
56
  const apiClient = this.props.formContext.apiClient;
57
- const fetch = (cache ? apiClient.fetchCached : apiClient.fetch).bind(apiClient);
58
57
  this.setState({ fetching: true });
59
- return fetch(path, query).then(result => {
58
+ return apiClient.get(path, { query }, cache).then(result => {
60
59
  if (result[resultKey]) {
61
60
  this.props.onChange(result[resultKey]);
62
61
  }
package/lib/validation.js CHANGED
@@ -39,7 +39,7 @@ exports.toErrorSchema = toErrorSchema;
39
39
  const lajiValidate = __importStar(require("@luomus/laji-validate"));
40
40
  function initializeValidation(apiClient) {
41
41
  lajiValidate.extend(lajiValidate.validators.remote, {
42
- fetch: (...params) => apiClient.fetchRaw(...params)
42
+ fetch: (...params) => apiClient.apiClient.fetch(...params)
43
43
  });
44
44
  }
45
45
  exports.default = ({ errors: error, warnings: warning }, data) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luomus/laji-form",
3
- "version": "15.1.66",
3
+ "version": "15.1.68",
4
4
  "description": "React module capable of building dynamic forms from Laji form json schemas",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -28,7 +28,8 @@
28
28
  "test:docker": "npm run test:docker:build && npm run test:docker:run --",
29
29
  "test:lightweight": "npx playwright test --project chromium",
30
30
  "test:docker:build": "docker build -t laji-form-test -f test.Dockerfile .",
31
- "test:docker:run": "docker run laji-form-test"
31
+ "test:docker:run": "docker run laji-form-test",
32
+ "generate:api-client": "openapi-typescript https://apitest.laji.fi/explorer-json -o ./generated/api.d.ts --properties-required-by-default"
32
33
  },
33
34
  "keywords": [
34
35
  "react-jsonschema-form",
@@ -71,7 +72,7 @@
71
72
  "@playwright/test": "^1.40.1",
72
73
  "@stylistic/eslint-plugin": "^5.4.0",
73
74
  "@types/jasmine": "^3.7.7",
74
- "@types/node": "^20.17.0",
75
+ "@types/node": "^24.5.2",
75
76
  "@typescript-eslint/eslint-plugin": "^8.44.1",
76
77
  "@typescript-eslint/parser": "^8.44.1",
77
78
  "copy-webpack-plugin": "^9.0.1",
@@ -82,6 +83,7 @@
82
83
  "eslint-plugin-react-hooks": "^5.2.0",
83
84
  "mini-css-extract-plugin": "^2.1.0",
84
85
  "notus": "^0.3.2",
86
+ "openapi-typescript": "^7.9.1",
85
87
  "querystring": "^0.2.1",
86
88
  "rimraf": "^2.5.4",
87
89
  "style-loader": "^3.0.0",