@luomus/laji-form 15.1.88 → 15.1.90

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.
package/dist/styles.css CHANGED
@@ -2389,8 +2389,10 @@ body .laji-form {
2389
2389
  margin-bottom: 0px;
2390
2390
  }
2391
2391
  .laji-form .autosuggest-wrapper .rw-list-option img {
2392
- border: 1px solid;
2393
2392
  float: right;
2393
+ }
2394
+ .laji-form .autosuggest-wrapper .rw-list-option img.flag-img {
2395
+ border: 1px solid;
2394
2396
  margin-top: 4px;
2395
2397
  }
2396
2398
 
@@ -146,6 +146,7 @@ const fields = importLocalComponents("fields", [
146
146
  "MultiActiveArrayField",
147
147
  "PrefixArrayField",
148
148
  "FillDateRangeField",
149
+ "ScientificNameTaxonAutosuggestField",
149
150
  { "InputTransformerField": "ConditionalOnChangeField" }, // Alias for backward compatibility.
150
151
  { "ConditionalField": "ConditionalUiSchemaField" }, // Alias for backward compatibility.
151
152
  { "UnitRapidField": "UnitShorthandField" }, // Alias for backward compatibility.
@@ -60,7 +60,7 @@ function EnumRangeArrayField(props) {
60
60
  propsOnChange(value);
61
61
  }, [propsOnChange]);
62
62
  const getEnumOptionsAsync = (0, react_1.useCallback)(() => __awaiter(this, void 0, void 0, function* () {
63
- const enums = yield props.formContext.apiClient.get(`/metadata/ranges/${range}`);
63
+ const enums = (yield props.formContext.apiClient.get("/metadata/alts/{alt}", { path: { alt: range } })).results;
64
64
  return enums.map(({ value }) => ({ value, label: value }));
65
65
  }), [props.formContext.apiClient, range]);
66
66
  const { Label } = props.formContext;
@@ -189,7 +189,7 @@ function MediaArrayField(ComposedComponent) {
189
189
  const metadataForm = this.state.metadataForm || {};
190
190
  if (typeof metadataModalOpen === "number" && !this.state.metadataForm) {
191
191
  const { metadataFormId = this.METADATA_FORM_ID } = (0, utils_1.getUiOptions)(this.props.uiSchema);
192
- this.apiClient.get("/forms/{id}", { path: { id: metadataFormId }, query: { lang, format: "schema" } })
192
+ this.apiClient.get("/forms/{id}", { path: { id: metadataFormId }, query: { format: "schema" } })
193
193
  .then(metadataForm => {
194
194
  if (this.mounted) {
195
195
  this.setState({ metadataForm });
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import { ByLang, FormContext } from "../../LajiForm";
3
3
  import memoize from "memoizee";
4
4
  import type { components } from "generated/api.d";
5
- type NamedPlace = components["schemas"]["namedPlace"];
5
+ type NamedPlace = components["schemas"]["store-namedPlace"];
6
6
  type Props = {
7
7
  places: NamedPlace[];
8
8
  failed?: boolean;
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { FieldProps, JSONSchemaArray, JSONSchemaObject } from "../../../types";
3
3
  import type { components } from "generated/api.d";
4
- type NamedPlace = components["schemas"]["namedPlace"];
4
+ type NamedPlace = components["schemas"]["store-namedPlace"];
5
5
  type Props = FieldProps<NamedPlace, JSONSchemaObject | JSONSchemaArray<JSONSchemaObject>>;
6
6
  type State = {
7
7
  show?: boolean;
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { FormContext } from "src/components/LajiForm";
3
3
  import type { components } from "generated/api.d";
4
- type NamedPlace = components["schemas"]["namedPlace"];
4
+ type NamedPlace = components["schemas"]["store-namedPlace"];
5
5
  type Props = {
6
6
  onPlaceSelected: (place: NamedPlace) => void;
7
7
  onPlaceDeleted: (place: NamedPlace) => void;
@@ -0,0 +1,39 @@
1
+ import * as React from "react";
2
+ import * as PropTypes from "prop-types";
3
+ import { FieldProps, JSONSchemaObject, JSONSchemaEnumOneOf } from "../../types";
4
+ interface State extends Pick<FieldProps<JSONSchemaObject>, "schema" | "uiSchema"> {
5
+ suggestion?: any;
6
+ }
7
+ interface ValueContext {
8
+ taxonRank?: string;
9
+ author?: string;
10
+ }
11
+ export default class ScientificNameTaxonAutosuggestField extends React.Component<FieldProps<JSONSchemaObject>, State> {
12
+ static contextType: React.Context<import("../../ReactContext").ContextProps>;
13
+ static propTypes: {
14
+ uiSchema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
15
+ "ui:options": PropTypes.Validator<NonNullable<PropTypes.InferProps<{
16
+ taxonField: PropTypes.Validator<string>;
17
+ taxonRankField: PropTypes.Validator<string>;
18
+ authorField: PropTypes.Validator<string>;
19
+ allowNonsuggestedValue: PropTypes.Requireable<boolean>;
20
+ }>>>;
21
+ uiSchema: PropTypes.Requireable<object>;
22
+ }>>>;
23
+ schema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
24
+ type: PropTypes.Requireable<string>;
25
+ }>>>;
26
+ formData: PropTypes.Validator<object>;
27
+ };
28
+ getStateFromProps: (props: FieldProps<JSONSchemaObject>) => State;
29
+ getSuggestionValue: (suggestion: any) => string;
30
+ onSuggestionSelected: (suggestion: any, mounted: boolean) => void;
31
+ onUnsuggestionSelected: (value: any) => void;
32
+ isValueSuggested: (value?: string, valueContext?: ValueContext) => boolean | undefined;
33
+ getSuggestionFromValue: (value?: string, valueContext?: ValueContext) => Promise<any>;
34
+ suggestionMatchesData: (suggestion: any, value?: string, valueContext?: ValueContext) => boolean;
35
+ getTaxonRankOptions: () => JSONSchemaEnumOneOf[] | undefined;
36
+ renderSuggestion(suggestion: any, inputValue?: string): JSX.Element;
37
+ render(): JSX.Element;
38
+ }
39
+ export {};
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
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
+ };
50
+ var __importDefault = (this && this.__importDefault) || function (mod) {
51
+ return (mod && mod.__esModule) ? mod : { "default": mod };
52
+ };
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ const React = __importStar(require("react"));
55
+ const PropTypes = __importStar(require("prop-types"));
56
+ const utils_1 = require("../../utils");
57
+ const ReactContext_1 = __importDefault(require("../../ReactContext"));
58
+ const AutosuggestWidget_1 = require("../widgets/AutosuggestWidget");
59
+ const BaseComponent_1 = __importDefault(require("../BaseComponent"));
60
+ const components_1 = require("../components");
61
+ function addBold(original, substring) {
62
+ const newOriginal = original.toLowerCase();
63
+ const newString = substring.toLowerCase();
64
+ const index = newOriginal.indexOf(newString);
65
+ return index > -1 ?
66
+ React.createElement(React.Fragment, null,
67
+ original.slice(0, index),
68
+ React.createElement("b", null, original.slice(index, index + substring.length)),
69
+ original.slice(index + substring.length))
70
+ : original;
71
+ }
72
+ let ScientificNameTaxonAutosuggestField = class ScientificNameTaxonAutosuggestField extends React.Component {
73
+ constructor() {
74
+ super(...arguments);
75
+ this.getStateFromProps = (props) => {
76
+ var _a;
77
+ let { schema, uiSchema, formData = {} } = props;
78
+ const uiOptions = (0, utils_1.getUiOptions)(uiSchema);
79
+ const { taxonField, taxonRankField, authorField } = uiOptions;
80
+ const scientificName = (0, utils_1.parseJSONPointer)(formData, taxonField, true);
81
+ const taxonRank = (0, utils_1.parseJSONPointer)(formData, taxonRankField, true);
82
+ const author = (0, utils_1.parseJSONPointer)(formData, authorField, true);
83
+ let taxonRankLabel = undefined;
84
+ if (taxonRank) {
85
+ taxonRankLabel = (_a = (this.getTaxonRankOptions() || []).find(option => option.const === taxonRank)) === null || _a === void 0 ? void 0 : _a.title;
86
+ }
87
+ let options = Object.assign(Object.assign({}, uiOptions), { autosuggestField: "taxon", onSuggestionSelected: this.onSuggestionSelected, onUnsuggestedSelected: this.onUnsuggestionSelected, isValueSuggested: this.isValueSuggested, getSuggestionFromValue: this.getSuggestionFromValue, getSuggestionValue: this.getSuggestionValue, renderSuggestion: this.renderSuggestion, valueContext: { taxonRank, author }, taxonRankLabel, Wrapper: TaxonWrapper });
88
+ if (!(0, utils_1.isEmptyString)(scientificName)) {
89
+ options.value = scientificName;
90
+ }
91
+ const innerUiSchema = (0, utils_1.getInnerUiSchema)(uiSchema);
92
+ const _uiSchemaJSONPointer = (0, utils_1.uiSchemaJSONPointer)(schema, taxonField);
93
+ if (!_uiSchemaJSONPointer) {
94
+ throw new Error("Invalid taxon field");
95
+ }
96
+ const taxonExistingUiSchema = (0, utils_1.parseJSONPointer)(innerUiSchema, _uiSchemaJSONPointer);
97
+ let widgetProps = taxonExistingUiSchema || {};
98
+ let _uiSchema = (0, utils_1.updateSafelyWithJSONPointer)(innerUiSchema, Object.assign(Object.assign({ "ui:widget": "AutosuggestWidget" }, widgetProps), { "ui:options": Object.assign(Object.assign({}, (0, utils_1.getUiOptions)((taxonExistingUiSchema || {})[taxonField])), options) }), _uiSchemaJSONPointer);
99
+ return { schema, uiSchema: _uiSchema };
100
+ };
101
+ this.getSuggestionValue = (suggestion) => {
102
+ return suggestion.scientificName;
103
+ };
104
+ this.onSuggestionSelected = (suggestion, mounted) => {
105
+ if (suggestion === null)
106
+ suggestion = undefined;
107
+ let { formData, uiSchema, formContext, registry, schema } = this.props;
108
+ const { taxonField, taxonRankField, authorField } = (0, utils_1.getUiOptions)(uiSchema);
109
+ if (typeof suggestion === "object") {
110
+ this.setState({ suggestion });
111
+ const scientificName = suggestion.scientificName;
112
+ formData = (0, utils_1.updateFormDataWithJSONPointer)({ formData, registry, schema }, scientificName, taxonField);
113
+ let taxonRank = suggestion.taxonRank;
114
+ const taxonRankOptions = this.getTaxonRankOptions();
115
+ if (taxonRankOptions && !taxonRankOptions.some(option => option.const === taxonRank)) {
116
+ taxonRank = undefined;
117
+ }
118
+ formData = (0, utils_1.updateFormDataWithJSONPointer)({ formData, registry, schema }, taxonRank, taxonRankField);
119
+ const author = suggestion.scientificNameAuthorship;
120
+ formData = (0, utils_1.updateFormDataWithJSONPointer)({ formData, registry, schema }, author, authorField);
121
+ }
122
+ if (mounted) {
123
+ this.props.onChange(formData);
124
+ }
125
+ else {
126
+ if (formContext.formDataTransformers) {
127
+ formData = formContext.formDataTransformers.reduce((unit, { "ui:field": uiField, props: fieldProps }) => {
128
+ let changed;
129
+ const getChanged = (_changed) => {
130
+ changed = _changed;
131
+ };
132
+ const field = new fieldProps.registry.fields[uiField](Object.assign(Object.assign({}, fieldProps), { formData: formData, onChange: getChanged }));
133
+ field.onChange(field.state && field.state.formData ? field.state.formData : formData);
134
+ return changed;
135
+ }, formData);
136
+ }
137
+ const lajiFormInstance = formContext.services.rootInstance;
138
+ const pointer = this.props.formContext.services.ids.getJSONPointerFromLajiFormIdAndFormDataAndIdSchemaId(this.props.idSchema.$id, (0, utils_1.getFieldUUID)(this.props));
139
+ const newFormData = Object.assign(Object.assign({}, (0, utils_1.parseJSONPointer)(lajiFormInstance.getFormData(), pointer)), formData);
140
+ lajiFormInstance.onChange((0, utils_1.updateSafelyWithJSONPointer)(lajiFormInstance.getFormData(), newFormData, pointer));
141
+ }
142
+ };
143
+ this.onUnsuggestionSelected = (value) => {
144
+ this.setState({ suggestion: undefined });
145
+ let { formData, uiSchema, registry, schema } = this.props;
146
+ const { taxonField } = (0, utils_1.getUiOptions)(uiSchema);
147
+ formData = (0, utils_1.updateFormDataWithJSONPointer)({ formData, registry, schema }, value, taxonField);
148
+ this.props.onChange(formData);
149
+ };
150
+ this.isValueSuggested = (value, valueContext) => {
151
+ const { suggestion } = this.state;
152
+ if (!suggestion) {
153
+ return false;
154
+ }
155
+ return this.suggestionMatchesData(suggestion, value, valueContext);
156
+ };
157
+ this.getSuggestionFromValue = (value, valueContext) => __awaiter(this, void 0, void 0, function* () {
158
+ if (this.isValueSuggested(value, valueContext)) {
159
+ return this.state.suggestion;
160
+ }
161
+ if (!value) {
162
+ throw new Error("Missing scientific name");
163
+ }
164
+ if (!(valueContext === null || valueContext === void 0 ? void 0 : valueContext.taxonRank)) {
165
+ throw new Error("Missing taxon rank");
166
+ }
167
+ const query = { query: value, limit: 100, nameTypes: "MX.scientificName", matchType: "exact" };
168
+ const result = yield this.props.formContext.apiClient.get("/autocomplete/taxa", { query });
169
+ for (const suggestion of result.results) {
170
+ if (this.suggestionMatchesData(suggestion, value, valueContext)) {
171
+ this.setState({ suggestion });
172
+ return suggestion;
173
+ }
174
+ }
175
+ throw new Error("Unknown scientific name");
176
+ });
177
+ this.suggestionMatchesData = (suggestion, value, valueContext) => {
178
+ var _a, _b, _c;
179
+ const normalizedValue = value === null || value === void 0 ? void 0 : value.replace(/\s+/g, " ").trim().toLowerCase();
180
+ const normalizedAuthor = (_a = valueContext === null || valueContext === void 0 ? void 0 : valueContext.author) === null || _a === void 0 ? void 0 : _a.replace(/\s/g, "").trim().toLowerCase();
181
+ return normalizedValue === ((_b = suggestion.scientificName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) &&
182
+ (valueContext === null || valueContext === void 0 ? void 0 : valueContext.taxonRank) === suggestion.taxonRank &&
183
+ normalizedAuthor === ((_c = suggestion.scientificNameAuthorship) === null || _c === void 0 ? void 0 : _c.replace(/\s/g, "").toLowerCase());
184
+ };
185
+ this.getTaxonRankOptions = () => {
186
+ let { uiSchema } = this.props;
187
+ const { taxonRankField } = (0, utils_1.getUiOptions)(uiSchema);
188
+ const taxonRankSchemaPointer = (0, utils_1.schemaJSONPointer)(this.props.schema, taxonRankField);
189
+ if (taxonRankSchemaPointer === undefined) {
190
+ throw new Error("Invalid taxon rank field");
191
+ }
192
+ return (0, utils_1.parseJSONPointer)(this.props.schema, taxonRankSchemaPointer).oneOf;
193
+ };
194
+ }
195
+ renderSuggestion(suggestion, inputValue) {
196
+ let value = suggestion.scientificName;
197
+ if (suggestion.nameType === "MX.scientificName" && inputValue) {
198
+ value = addBold(value, inputValue);
199
+ }
200
+ return (React.createElement("span", { className: "simple-option" },
201
+ React.createElement(React.Fragment, null,
202
+ value,
203
+ (0, AutosuggestWidget_1.renderTaxonIcons)(suggestion))));
204
+ }
205
+ render() {
206
+ const { SchemaField } = this.props.registry.fields;
207
+ return React.createElement(SchemaField, Object.assign({}, this.props, { uiSchema: this.state.uiSchema }));
208
+ }
209
+ };
210
+ ScientificNameTaxonAutosuggestField.contextType = ReactContext_1.default;
211
+ ScientificNameTaxonAutosuggestField.propTypes = {
212
+ uiSchema: PropTypes.shape({
213
+ "ui:options": PropTypes.shape({
214
+ taxonField: PropTypes.string.isRequired,
215
+ taxonRankField: PropTypes.string.isRequired,
216
+ authorField: PropTypes.string.isRequired,
217
+ allowNonsuggestedValue: PropTypes.bool
218
+ }).isRequired,
219
+ uiSchema: PropTypes.object
220
+ }).isRequired,
221
+ schema: PropTypes.shape({
222
+ type: PropTypes.oneOf(["object"])
223
+ }).isRequired,
224
+ formData: PropTypes.object.isRequired
225
+ };
226
+ ScientificNameTaxonAutosuggestField = __decorate([
227
+ BaseComponent_1.default
228
+ ], ScientificNameTaxonAutosuggestField);
229
+ exports.default = ScientificNameTaxonAutosuggestField;
230
+ class _TaxonWrapper extends React.Component {
231
+ render() {
232
+ const { id, formContext, suggestion, children, placement, inputValue, isSuggested, options } = this.props;
233
+ const { Popover, Tooltip } = this.context.theme;
234
+ const tooltipElem = (React.createElement(Tooltip, { id: `${id}-popover-tooltip` }, formContext.translations.OpenSpeciedCard));
235
+ const taxonLinkElem = (React.createElement(components_1.OverlayTrigger, { overlay: tooltipElem, style: { display: "inline" } },
236
+ React.createElement("a", { href: `http://tun.fi/${suggestion === null || suggestion === void 0 ? void 0 : suggestion.id}`, target: "_blank", rel: "noopener noreferrer" }, suggestion === null || suggestion === void 0 ? void 0 : suggestion.id)));
237
+ let popover;
238
+ if ((0, utils_1.isEmptyString)(inputValue)) {
239
+ popover = React.createElement(React.Fragment, null);
240
+ }
241
+ else {
242
+ popover = (React.createElement(Popover, { id: `${id}-popover` },
243
+ !isSuggested && this.props.formContext.translations.UnknownName,
244
+ isSuggested && (React.createElement("div", null, options === null || options === void 0 ? void 0 :
245
+ options.taxonRankLabel,
246
+ " ",
247
+ suggestion.cursiveName ? React.createElement("i", null, suggestion.scientificName) : suggestion.scientificName,
248
+ " ",
249
+ suggestion.scientificNameAuthorship,
250
+ " ",
251
+ (0, AutosuggestWidget_1.renderTaxonIcons)(suggestion),
252
+ " (",
253
+ taxonLinkElem,
254
+ ")"))));
255
+ }
256
+ return (React.createElement(components_1.OverlayTrigger, { hoverable: true, placement: placement, overlay: popover, ref: this.props.overlayRef, formContext: this.props.formContext }, children));
257
+ }
258
+ }
259
+ _TaxonWrapper.contextType = ReactContext_1.default;
260
+ const TaxonWrapper = React.forwardRef((props, ref) => React.createElement(_TaxonWrapper, Object.assign({}, props, { overlayRef: ref })));
@@ -1,3 +1,4 @@
1
+ export function renderTaxonIcons(suggestion: any, prepend: any): JSX.Element | null;
1
2
  export default class _AutosuggestWidget extends React.Component<any, any, any> {
2
3
  static propTypes: {
3
4
  schema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
@@ -22,6 +23,7 @@ export class Autosuggest extends React.Component<any, any, any> {
22
23
  informalTaxonGroups: PropTypes.Requireable<string>;
23
24
  onInformalTaxonGroupSelected: PropTypes.Requireable<(...args: any[]) => any>;
24
25
  cache: PropTypes.Requireable<boolean>;
26
+ valueContext: PropTypes.Requireable<object>;
25
27
  };
26
28
  static defaultProps: {
27
29
  allowNonsuggestedValue: boolean;
@@ -43,12 +45,13 @@ export class Autosuggest extends React.Component<any, any, any> {
43
45
  mounted: boolean | undefined;
44
46
  componentWillUnmount(): void;
45
47
  componentDidUpdate(prevProps: any): void;
48
+ triggerConvertTimeout: any;
46
49
  keyFunctions: {
47
50
  autosuggestToggle: () => boolean;
48
51
  };
49
52
  triggerConvert: (props: any) => void;
50
53
  getSuggestionValue: (suggestion: any) => any;
51
- renderSuggestion: (suggestion: any) => JSX.Element;
54
+ renderSuggestion: (suggestion: any, inputValue: any) => JSX.Element;
52
55
  selectSuggestion: (suggestion: any) => void;
53
56
  selectUnsuggested: (inputValue: any) => void;
54
57
  onSuggestionSelected: (suggestion: any) => void;
@@ -63,6 +63,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
63
63
  };
64
64
  Object.defineProperty(exports, "__esModule", { value: true });
65
65
  exports.Autosuggest = void 0;
66
+ exports.renderTaxonIcons = renderTaxonIcons;
66
67
  const React = __importStar(require("react"));
67
68
  const react_dom_1 = require("react-dom");
68
69
  const PropTypes = __importStar(require("prop-types"));
@@ -71,11 +72,16 @@ const utils_1 = require("../../utils");
71
72
  const components_1 = require("../components");
72
73
  const ReactContext_1 = __importDefault(require("../../ReactContext"));
73
74
  const InformalTaxonGroupChooserWidget_1 = require("./InformalTaxonGroupChooserWidget");
74
- function renderFlag(suggestion, prepend) {
75
- return (suggestion || {}).finnish
75
+ const utils_2 = require("@rjsf/utils");
76
+ function renderTaxonIcons(suggestion, prepend) {
77
+ const { finnish, checklist } = suggestion || {};
78
+ const flagIcon = finnish ? React.createElement("img", { src: "https://cdn.laji.fi/images/icons/flag_fi_small.png", width: "16", className: "flag-img" }) : null;
79
+ const gbifIcon = checklist === "MR.2" ? React.createElement("img", { src: "https://cdn.laji.fi/images/icons/gbif.svg", width: "18" }) : null;
80
+ return flagIcon || gbifIcon
76
81
  ? React.createElement(React.Fragment, null,
77
82
  prepend || null,
78
- React.createElement("img", { src: "https://cdn.laji.fi/images/icons/flag_fi_small.png", width: "16" }))
83
+ flagIcon,
84
+ gbifIcon)
79
85
  : null;
80
86
  }
81
87
  class _AutosuggestWidget extends React.Component {
@@ -248,7 +254,7 @@ function TaxonAutosuggest(ComposedComponent) {
248
254
  && React.createElement("span", { dangerouslySetInnerHTML: { __html: suggestion.autocompleteDisplayName } })
249
255
  || React.createElement(React.Fragment, null,
250
256
  suggestion.value,
251
- renderFlag(suggestion));
257
+ renderTaxonIcons(suggestion));
252
258
  return React.createElement("span", { className: "simple-option" }, renderedSuggestion);
253
259
  }
254
260
  render() {
@@ -303,7 +309,7 @@ let UnitAutosuggestWidget = class UnitAutosuggestWidget extends React.Component
303
309
  maleElem,
304
310
  femaleElem && " ",
305
311
  femaleElem,
306
- renderFlag(suggestion));
312
+ renderTaxonIcons(suggestion));
307
313
  }
308
314
  };
309
315
  UnitAutosuggestWidget = __decorate([
@@ -456,7 +462,7 @@ class Autosuggest extends React.Component {
456
462
  const { isValueSuggested, suggestionReceive, onSuggestionSelected } = props;
457
463
  if (!onSuggestionSelected && suggestionReceive !== "key")
458
464
  return undefined;
459
- return isValueSuggested ? isValueSuggested(props.value) : undefined;
465
+ return isValueSuggested ? isValueSuggested(props.value, props.valueContext) : undefined;
460
466
  };
461
467
  this.wrapperRef = React.createRef();
462
468
  this.keyFunctions = {
@@ -469,7 +475,7 @@ class Autosuggest extends React.Component {
469
475
  }
470
476
  };
471
477
  this.triggerConvert = (props) => {
472
- const { value, getSuggestionFromValue } = props;
478
+ const { value, getSuggestionFromValue, valueContext } = props;
473
479
  if ((0, utils_1.isEmptyString)(value) || !getSuggestionFromValue) {
474
480
  if (this.state.suggestion && Object.keys(this.state.suggestion).length > 0) {
475
481
  this.setState({ suggestion: undefined, inputValue: value, suggestionForValue: value });
@@ -477,7 +483,7 @@ class Autosuggest extends React.Component {
477
483
  return;
478
484
  }
479
485
  this.setState({ isLoading: true });
480
- getSuggestionFromValue(value).then(suggestion => {
486
+ getSuggestionFromValue(value, valueContext).then(suggestion => {
481
487
  if (!this.mounted)
482
488
  return;
483
489
  this.setState({ suggestion, inputValue: this.getSuggestionValue(suggestion), isLoading: false, suggestionForValue: value });
@@ -494,11 +500,11 @@ class Autosuggest extends React.Component {
494
500
  ? getSuggestionValue(suggestion, def)
495
501
  : def;
496
502
  };
497
- this.renderSuggestion = (suggestion) => {
503
+ this.renderSuggestion = (suggestion, inputValue) => {
498
504
  let { renderSuggestion } = this.props;
499
505
  if (!renderSuggestion)
500
506
  renderSuggestion = suggestion => suggestion.value;
501
- return (React.createElement("span", null, renderSuggestion(suggestion)));
507
+ return (React.createElement("span", null, renderSuggestion(suggestion, inputValue)));
502
508
  };
503
509
  this.selectSuggestion = (suggestion) => {
504
510
  const { onSuggestionSelected, onChange, suggestionReceive } = this.props;
@@ -764,7 +770,7 @@ class Autosuggest extends React.Component {
764
770
  const input = (React.createElement(components_1.FetcherInput, Object.assign({ value: inputValue, glyph: glyph, loading: this.state.isLoading, validationState: validationState, extra: [addon, toggler] }, inputProps)));
765
771
  let component = input;
766
772
  if (displayValidationState && Wrapper) {
767
- component = (React.createElement(Wrapper, { isSuggested: isSuggested, suggestion: suggestion, options: (0, utils_1.getUiOptions)(this.props), id: this.props.id, value: suggestion && suggestion.key, inputValue: value, ref: this.wrapperRef, formContext: this.props.formContext }, component));
773
+ component = (React.createElement(Wrapper, { isSuggested: isSuggested, suggestion: suggestion, options: (0, utils_1.getUiOptions)(this.props.uiSchema), id: this.props.id, value: suggestion && suggestion.key, inputValue: value, ref: this.wrapperRef, formContext: this.props.formContext }, component));
768
774
  }
769
775
  if (informalTaxonGroups) {
770
776
  component = (React.createElement(React.Fragment, null,
@@ -793,13 +799,34 @@ class Autosuggest extends React.Component {
793
799
  this.props.formContext.services.keyHandler.removeKeyHandler(this.props.id, this.keyFunctions);
794
800
  }
795
801
  componentDidUpdate(prevProps) {
796
- if (!this.props.controlledValue && this.state.suggestion && this.props && prevProps.value !== this.props.value && this.props.value !== this.state.suggestionForValue) {
797
- this.props.getSuggestionFromValue(this.props.value).then(suggestion => {
802
+ if (this.props.controlledValue) {
803
+ return;
804
+ }
805
+ const valueChanged = this.state.suggestion && this.props && prevProps.value !== this.props.value && this.props.value !== this.state.suggestionForValue;
806
+ const valueContextChanged = !(0, utils_2.deepEquals)(prevProps.valueContext, this.props.valueContext);
807
+ if (valueChanged) {
808
+ this.props.getSuggestionFromValue(this.props.value, this.props.valueContext).then(suggestion => {
798
809
  this.setState({ inputValue: this.getSuggestionValue(suggestion), suggestion });
799
810
  }, () => {
800
- this.setState({ inputValue: "", suggestion: undefined });
811
+ const state = { suggestion: undefined };
812
+ if (!this.props.allowNonsuggestedValue) {
813
+ state.inputValue = "";
814
+ }
815
+ this.setState(state);
801
816
  });
802
817
  }
818
+ else if (valueContextChanged) {
819
+ this.setState({ isLoading: true });
820
+ if (this.triggerConvertTimeout) {
821
+ clearTimeout(this.triggerConvertTimeout);
822
+ }
823
+ // debounce trigger convert function so that it's not called too frequently
824
+ this.triggerConvertTimeout = this.props.formContext.setTimeout(() => {
825
+ if (!this.mounted)
826
+ return;
827
+ this.triggerConvert(this.props);
828
+ }, 100);
829
+ }
803
830
  }
804
831
  render() {
805
832
  const { props } = this;
@@ -833,7 +860,8 @@ Autosuggest.propTypes = {
833
860
  uiSchema: PropTypes.object,
834
861
  informalTaxonGroups: PropTypes.string,
835
862
  onInformalTaxonGroupSelected: PropTypes.func,
836
- cache: PropTypes.bool
863
+ cache: PropTypes.bool,
864
+ valueContext: PropTypes.object
837
865
  };
838
866
  Autosuggest.defaultProps = {
839
867
  allowNonsuggestedValue: true,
@@ -861,10 +889,10 @@ class _TaxonWrapper extends React.Component {
861
889
  this.setState({ scientificName: "", cursiveName: false });
862
890
  }
863
891
  else {
864
- this.props.formContext.apiClient.get(`/taxa/${value}`).then(({ scientificName, cursiveName, vernacularName, taxonRank, informalGroups, finnish }) => {
892
+ this.props.formContext.apiClient.get(`/taxa/${value}`).then(({ scientificName, cursiveName, vernacularName, taxonRank, informalGroups, finnish, checklist }) => {
865
893
  if (!this.mounted)
866
894
  return;
867
- this.setState({ value, taxonRank, informalTaxonGroups: informalGroups, taxon: { scientificName, vernacularName, cursiveName, finnish } });
895
+ this.setState({ value, taxonRank, informalTaxonGroups: informalGroups, taxon: { scientificName, vernacularName, cursiveName, finnish, checklist } });
868
896
  (0, InformalTaxonGroupChooserWidget_1.getInformalGroups)(this.props.formContext.apiClient).then(({ informalTaxonGroupsById }) => {
869
897
  if (!this.mounted)
870
898
  return;
@@ -889,7 +917,7 @@ class _TaxonWrapper extends React.Component {
889
917
  }
890
918
  }
891
919
  this.setState(Object.assign(Object.assign({}, state), { higherThanOrder: !state.order && !state.family }));
892
- const taxonRanks = yield this.props.formContext.apiClient.get("/metadata/ranges/MX.taxonRankEnum");
920
+ const taxonRanks = (yield this.props.formContext.apiClient.get("/metadata/properties/MX.taxonRank/alt")).results;
893
921
  if (!this.mounted)
894
922
  return;
895
923
  this.setState({ taxonRanks: (0, utils_1.dictionarify)(taxonRanks, function getKey(rank) { return rank.id; }, function getValue(rank) { return rank.value; }) });
@@ -1049,14 +1077,14 @@ class TaxonImgChooser extends React.Component {
1049
1077
  }
1050
1078
  }
1051
1079
  TaxonImgChooser.contextType = ReactContext_1.default;
1052
- const TaxonName = ({ scientificName, vernacularName = "", cursiveName, finnish }) => {
1080
+ const TaxonName = ({ scientificName, vernacularName = "", cursiveName, finnish, checklist }) => {
1053
1081
  const _scientificName = vernacularName && scientificName
1054
1082
  ? `(${scientificName})`
1055
1083
  : (scientificName || "");
1056
1084
  return (React.createElement(React.Fragment, null,
1057
1085
  `${vernacularName}${vernacularName ? " " : ""}`,
1058
1086
  cursiveName ? React.createElement("i", null, _scientificName) : _scientificName,
1059
- renderFlag({ finnish }, " ")));
1087
+ renderTaxonIcons({ finnish, checklist }, " ")));
1060
1088
  };
1061
1089
  class ReactAutosuggest extends React.Component {
1062
1090
  constructor(props) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luomus/laji-form",
3
- "version": "15.1.88",
3
+ "version": "15.1.90",
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",